parallax/jsPDF · error · Error
TTCF not supported.
Error message
TTCF not supported.
What it means
Thrown by the TTFFont constructor when the 4 bytes at offset 4 of the font data spell 'ttcf', identifying a TrueType Collection (.ttc) file. jsPDF's font engine only supports single-face TrueType (.ttf), so it refuses a collection outright rather than attempting partial parsing.
Source
Thrown at src/libs/ttffont.js:33
/************************************************************************/
/* function : open */
/* comment : Decode the encoded ttf content and create a TTFFont object. */
/************************************************************************/
TTFFont.open = function(file) {
return new TTFFont(file);
};
/***************************************************************/
/* function : TTFFont gernerator */
/* comment : Decode TTF contents are parsed, Data, */
/* Subset object is created, and registerTTF function is called.*/
/***************************************************************/
function TTFFont(rawData) {
var data;
this.rawData = rawData;
data = this.contents = new Data(rawData);
this.contents.pos = 4;
if (data.readString(4) === "ttcf") {
throw new Error("TTCF not supported.");
} else {
data.pos = 0;
this.parse();
this.subset = new Subset(this);
this.registerTTF();
}
}
/********************************************************/
/* function : parse */
/* comment : TTF Parses the file contents by each table.*/
/********************************************************/
TTFFont.prototype.parse = function() {
this.directory = new Directory(this.contents);
this.head = new HeadTable(this);
this.name = new NameTable(this);
this.cmap = new CmapTable(this);
this.toUnicode = {};
this.hhea = new HheaTable(this);View on GitHub (pinned to a3930ce03a)
Solutions
- Use a single-face .ttf file instead of a .ttc collection.
- Extract one face from the .ttc using fonttools (`pyftsubset`/`ttx`) or fontforge before registering it.
- Verify the font bytes are not 'ttcf' at offset 4 before calling addFont.
Example fix
// before
var font = loadFont('NotoSans.ttc'); // collection
doc.addFileToVFS('NotoSans.ttf', font);
doc.addFont('NotoSans.ttf', 'NotoSans', 'normal');
// after (extract one face to a real .ttf first)
var font = loadFont('NotoSans-Regular.ttf'); // single face, offset 4 != 'ttcf'
doc.addFileToVFS('NotoSans-Regular.ttf', font);
doc.addFont('NotoSans-Regular.ttf', 'NotoSans', 'normal'); Defensive patterns
Strategy: validation
Validate before calling
function isSingleFaceTtf(bytes) {
// a .ttc has 'ttcf' at offset 4; a single .ttf has its sfnt version at offset 0
var s = String.fromCharCode(bytes[4], bytes[5], bytes[6], bytes[7]);
return s !== 'ttcf';
}
if (!isSingleFaceTtf(fontBytes)) {
throw new Error('Font is a .ttc collection; extract a single .ttf face first');
} Type guard
function isSingleFaceTtf(bytes) {
if (!(bytes instanceof Uint8Array) || bytes.length < 8) return false;
return String.fromCharCode(bytes[4], bytes[5], bytes[6], bytes[7]) !== 'ttcf';
} Try / catch
try {
doc.addFont(fontKey, family, style);
} catch (e) {
if (/TTCF not supported/.test(e.message)) {
throw new Error('Please provide a single-face .ttf, not a .ttc collection');
}
throw e;
} Prevention
- Always register single-face .ttf files, never .ttc collections.
- Extract a face with fonttools/pyftsubset or fontforge before embedding.
- Check offset-4 magic for 'ttcf' during your font onboarding step.
When it happens
Trigger: Passing a .ttc font (which packages multiple TTF faces) through addFileToVFS + addFont, or directly via TTFFont.open(file). The magic bytes 'ttcf' at offset 4 are read and rejected before any table parsing.
Common situations: Bundling a system font that is actually a .ttc (common on macOS/Windows for CJK families like PingFang or MS Mincho); converting a .otf/.ttc without extracting a single face.
Related errors
- No unicode cmap for font
- Invalid Combination of fontweight and fontstyle
- Invalid PDF Name Object: " + str + ", Only accept ASCII char
- Invalid arguments passed to PubSub.subscribe (jsPDF-module)
- Invalid argument passed to jsPDF.setCreationDate
AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13).
Data as JSON: /api/errors/e70b0aab5ee469e8.
Report an issue: GitHub.