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

  1. Use a single-face .ttf file instead of a .ttc collection.
  2. Extract one face from the .ttc using fonttools (`pyftsubset`/`ttx`) or fontforge before registering it.
  3. 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

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


AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13). Data as JSON: /api/errors/e70b0aab5ee469e8. Report an issue: GitHub.