# cffLib: read/write Adobe CFF fonts

cffLib: read/write Adobe CFF fonts

OpenType fonts with PostScript outlines contain a completely independent font file, Adobe’s Compact Font Format. So dealing with OpenType fonts requires also dealing with CFF. This module allows you to read and write fonts written in the CFF format.

In 2016, OpenType 1.8 introduced the CFF2 format which, along with other changes, extended the CFF format to deal with the demands of variable fonts. This module parses both original CFF and CFF2.

class fontTools.cffLib.CFFFontSet

  A CFF font “file” can contain more than one font, although this is extremely rare (and not allowed within OpenType fonts).

  This class is the entry point for parsing a CFF table. To actually manipulate the data inside the CFF font, you will want to access the `CFFFontSet`’s `TopDict` object. To do this, a `CFFFontSet` object can either be treated as a dictionary (with appropriate `keys()` and `values()` methods) mapping font names to `TopDict` objects, or as a list.

      from fontTools import ttLib
      tt = ttLib.TTFont("Tests/cffLib/data/LinLibertine_RBI.otf")
      tt["CFF "].cff
      # <fontTools.cffLib.CFFFontSet object at 0x101e24c90>
      tt["CFF "].cff[0] # Here's your actual font data
      # <fontTools.cffLib.TopDict object at 0x1020f1fd0>

  compile(file, otFont, isCFF2=None)

    Write the object back into binary representation onto the given file. `file` should be a file handle object. `otFont` is the top-level `fontTools.ttLib.ttFont.TTFont` object containing this CFF file.

    If `isCFF2` is passed and set to `True` or `False`, then the library makes an assertion that the CFF header is of the appropriate version.

  convertCFFToCFF2(otFont)

    Converts this object from CFF format to CFF2 format. This conversion is done ‘in-place’. The conversion cannot be reversed.

    This assumes a decompiled CFF table. (i.e. that the object has been filled via `decompile()`.)

  decompile(file, otFont, isCFF2=None)

    Parse a binary CFF file into an internal representation. `file` should be a file handle object. `otFont` is the top-level `fontTools.ttLib.ttFont.TTFont` object containing this CFF file.

    If `isCFF2` is passed and set to `True` or `False`, then the library makes an assertion that the CFF header is of the appropriate version.

  fromXML(name, attrs, content, otFont=None)

    Reads data from the XML element into the `CFFFontSet` object.

  toXML(xmlWriter)

    Write the object into XML representation onto the given `fontTools.misc.xmlWriter.XMLWriter`.

        writer = xmlWriter.XMLWriter(sys.stdout)
        tt["CFF "].cff.toXML(writer)

class fontTools.cffLib.CFFWriter(isCFF2)

  Helper class for serializing CFF data to binary. Used by `CFFFontSet.compile()`.

class fontTools.cffLib.CharStrings(file, charset, globalSubrs, private, fdSelect, fdArray, isCFF2=None, varStore=None)

  The `CharStrings` in the font represent the instructions for drawing each glyph. This object presents a dictionary interface to the font’s CharStrings, indexed by glyph name:

      tt["CFF "].cff[0].CharStrings["a"]
      # <T2CharString (bytecode) at 103451e90>

  See `fontTools.misc.psCharStrings.T1CharString` and `fontTools.misc.psCharStrings.T2CharString` for how to decompile, compile and interpret the glyph drawing instructions in the returned objects.

class fontTools.cffLib.CharStringsCompiler(items, strings, parent, isCFF2=None)

  Helper class for writing the CharStrings INDEX to binary.

class fontTools.cffLib.FDArrayIndex(file=None, isCFF2=None)
  append(item)

    Add an item to an INDEX.

  clear()

    Empty the INDEX.

  compilerClass

    alias of `FDArrayIndexCompiler`

class fontTools.cffLib.FDArrayIndexCompiler(items, strings, parent, isCFF2=None)

  Helper class for writing the Font DICT INDEX to binary.

class fontTools.cffLib.GlobalSubrsCompiler(items, strings, parent, isCFF2=None)

  Helper class for writing the global subroutine INDEX to binary.

class fontTools.cffLib.GlobalSubrsIndex(file=None, globalSubrs=None, private=None, fdSelect=None, fdArray=None, isCFF2=None)

  This index contains all the global subroutines in the font. A global subroutine is a set of `CharString` data which is accessible to any glyph in the font, and are used to store repeated instructions - for example, components may be encoded as global subroutines, but so could hinting instructions.

  Remember that when interpreting a `callgsubr` instruction (or indeed a `callsubr` instruction) that you will need to add the “subroutine number bias” to number given:

      tt = ttLib.TTFont("Almendra-Bold.otf")
      u = tt["CFF "].cff[0].CharStrings["udieresis"]
      u.decompile()

      u.toXML(XMLWriter(sys.stdout))
      # <some stuff>
      # -64 callgsubr <-- Subroutine which implements the dieresis mark
      # <other stuff>

      tt["CFF "].cff[0].GlobalSubrs[-64] # <-- WRONG
      # <T2CharString (bytecode) at 103451d10>

      tt["CFF "].cff[0].GlobalSubrs[-64 + 107] # <-- RIGHT
      # <T2CharString (source) at 103451390>

  (“The bias applied depends on the number of subrs (gsubrs). If the number of subrs (gsubrs) is less than 1240, the bias is 107. Otherwise if it is less than 33900, it is 1131; otherwise it is 32768.”, Subroutine Operators <https://docs.microsoft.com/en-us/typography/opentype/otspec180/cff2charstr#section4.4>)

  append(item)

    Add an item to an INDEX.

  clear()

    Empty the INDEX.

  compilerClass

    alias of `GlobalSubrsCompiler`

  toXML(xmlWriter)

    Write the subroutines index into XML representation onto the given `fontTools.misc.xmlWriter.XMLWriter`.

        writer = xmlWriter.XMLWriter(sys.stdout)
        tt["CFF "].cff[0].GlobalSubrs.toXML(writer)

class fontTools.cffLib.Index(file=None, isCFF2=None)

  This class represents what the CFF spec calls an INDEX (an array of variable-sized objects). Index items can be addressed and set using Python list indexing.

  append(item)

    Add an item to an INDEX.

  clear()

    Empty the INDEX.

  compilerClass

    alias of `IndexCompiler`

class fontTools.cffLib.IndexCompiler(items, strings, parent, isCFF2=None)

  Base class for writing CFF INDEX data to binary.

class fontTools.cffLib.IndexedStrings(file=None)

  SID -> string mapping.

class fontTools.cffLib.IndexedStringsCompiler(items, strings, parent, isCFF2=None)

exception fontTools.cffLib.StopHintCountEvent
  add_note()

    Exception.add_note(note) – add a note to the exception

  with_traceback()

    Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class fontTools.cffLib.SubrsCompiler(items, strings, parent, isCFF2=None)

  Helper class for writing the local subroutine INDEX to binary.

class fontTools.cffLib.SubrsIndex(file=None, globalSubrs=None, private=None, fdSelect=None, fdArray=None, isCFF2=None)

  This index contains a glyph’s local subroutines. A local subroutine is a private set of `CharString` data which is accessible only to the glyph to which the index is attached.

  append(item)

    Add an item to an INDEX.

  clear()

    Empty the INDEX.

  compilerClass

    alias of `SubrsCompiler`

  toXML(xmlWriter)

    Write the subroutines index into XML representation onto the given `fontTools.misc.xmlWriter.XMLWriter`.

        writer = xmlWriter.XMLWriter(sys.stdout)
        tt["CFF "].cff[0].GlobalSubrs.toXML(writer)

class fontTools.cffLib.TopDict(strings=None, file=None, offset=None, GlobalSubrs=None, cff2GetGlyphOrder=None, isCFF2=None)

  The `TopDict` represents the top-level dictionary holding font information. CFF2 tables contain a restricted set of top-level entries as described here, but CFF tables may contain a wider range of information. This information can be accessed through attributes or through the dictionary returned through the `rawDict` property:

      font = tt["CFF "].cff[0]
      font.FamilyName
      # 'Linux Libertine O'
      font.rawDict["FamilyName"]
      # 'Linux Libertine O'

  More information is available in the CFF file’s private dictionary, accessed via the `Private` property:

      tt["CFF "].cff[0].Private.BlueValues
      # [-15, 0, 515, 515, 666, 666]

  getGlyphOrder()

    Returns a list of glyph names in the CFF font.

class fontTools.cffLib.TopDictIndex(file=None, cff2GetGlyphOrder=None, topSize=0, isCFF2=None)

  This index represents the array of `TopDict` structures in the font (again, usually only one entry is present). Hence the following calls are equivalent:

      tt["CFF "].cff[0]
      # <fontTools.cffLib.TopDict object at 0x102ed6e50>
      tt["CFF "].cff.topDictIndex[0]
      # <fontTools.cffLib.TopDict object at 0x102ed6e50>

  append(item)

    Add an item to an INDEX.

  clear()

    Empty the INDEX.

  compilerClass

    alias of `TopDictIndexCompiler`

class fontTools.cffLib.TopDictIndexCompiler(items, strings, parent, isCFF2=None)

  Helper class for writing the TopDict to binary.

This package also contains two modules for manipulating CFF format glyphs:

- specializer: T2CharString operator specializer and generalizer
- width: T2CharString glyph width optimizer