[docs] Source documentation for cffLib (#1935)
* [docs] Source documentation for cffLib * Address feedback
This commit is contained in:
parent
847c31c4f2
commit
8d32a24710
@ -1,6 +1,10 @@
|
|||||||
######
|
##################################
|
||||||
cffLib
|
cffLib: read/write Adobe CFF fonts
|
||||||
######
|
##################################
|
||||||
|
|
||||||
|
.. automodule:: fontTools.cffLib
|
||||||
|
|
||||||
|
This package also contains two modules for manipulating CFF format glyphs:
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
@ -8,7 +12,42 @@ cffLib
|
|||||||
specializer
|
specializer
|
||||||
width
|
width
|
||||||
|
|
||||||
.. automodule:: fontTools.cffLib
|
.. autoclass:: fontTools.cffLib.CFFFontSet
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
|
||||||
|
.. autoclass:: fontTools.cffLib.TopDict
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.CharStrings
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.Index
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.GlobalSubrsIndex
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.TopDictIndex
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.CFFWriter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.IndexCompiler
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.TopDictIndexCompiler
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.FDArrayIndexCompiler
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.GlobalSubrsCompiler
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.SubrsCompiler
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: fontTools.cffLib.CharStringsCompiler
|
||||||
|
:members:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
###########
|
##############################################################
|
||||||
specializer
|
specializer: T2CharString operator specializer and generalizer
|
||||||
###########
|
##############################################################
|
||||||
|
|
||||||
.. automodule:: fontTools.cffLib.specializer
|
.. automodule:: fontTools.cffLib.specializer
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#####
|
#########################################
|
||||||
width
|
width: T2CharString glyph width optimizer
|
||||||
#####
|
#########################################
|
||||||
|
|
||||||
.. automodule:: fontTools.cffLib.width
|
.. automodule:: fontTools.cffLib.width
|
||||||
:inherited-members:
|
:members: optimizeWidths, optimizeWidthsBruteforce
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
@ -1,4 +1,15 @@
|
|||||||
"""cffLib.py -- read/write tools for 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 <https://docs.microsoft.com/en-us/typography/opentype/spec/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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.misc import sstruct
|
from fontTools.misc import sstruct
|
||||||
@ -28,8 +39,37 @@ maxStackLimit = 513
|
|||||||
|
|
||||||
|
|
||||||
class CFFFontSet(object):
|
class CFFFontSet(object):
|
||||||
|
"""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 :class:`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 :class:`TopDict`
|
||||||
|
objects, or as a list.
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
def decompile(self, file, otFont, isCFF2=None):
|
def decompile(self, 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
|
||||||
|
:py:class:`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.
|
||||||
|
"""
|
||||||
|
|
||||||
self.otFont = otFont
|
self.otFont = otFont
|
||||||
sstruct.unpack(cffHeaderFormat, file.read(3), self)
|
sstruct.unpack(cffHeaderFormat, file.read(3), self)
|
||||||
if isCFF2 is not None:
|
if isCFF2 is not None:
|
||||||
@ -89,6 +129,14 @@ class CFFFontSet(object):
|
|||||||
return self.topDictIndex[index]
|
return self.topDictIndex[index]
|
||||||
|
|
||||||
def compile(self, file, otFont, isCFF2=None):
|
def compile(self, 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
|
||||||
|
:py:class:`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.
|
||||||
|
"""
|
||||||
self.otFont = otFont
|
self.otFont = otFont
|
||||||
if isCFF2 is not None:
|
if isCFF2 is not None:
|
||||||
# called from ttLib: assert 'major' value matches expected version
|
# called from ttLib: assert 'major' value matches expected version
|
||||||
@ -144,6 +192,16 @@ class CFFFontSet(object):
|
|||||||
writer.toFile(file)
|
writer.toFile(file)
|
||||||
|
|
||||||
def toXML(self, xmlWriter):
|
def toXML(self, xmlWriter):
|
||||||
|
"""Write the object into XML representation onto the given
|
||||||
|
:class:`fontTools.misc.xmlWriter.XMLWriter`.
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
writer = xmlWriter.XMLWriter(sys.stdout)
|
||||||
|
tt["CFF "].cff.toXML(writer)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
xmlWriter.simpletag("major", value=self.major)
|
xmlWriter.simpletag("major", value=self.major)
|
||||||
xmlWriter.newline()
|
xmlWriter.newline()
|
||||||
xmlWriter.simpletag("minor", value=self.minor)
|
xmlWriter.simpletag("minor", value=self.minor)
|
||||||
@ -163,6 +221,7 @@ class CFFFontSet(object):
|
|||||||
xmlWriter.newline()
|
xmlWriter.newline()
|
||||||
|
|
||||||
def fromXML(self, name, attrs, content, otFont=None):
|
def fromXML(self, name, attrs, content, otFont=None):
|
||||||
|
"""Reads data from the XML element into the ``CFFFontSet`` object."""
|
||||||
self.otFont = otFont
|
self.otFont = otFont
|
||||||
|
|
||||||
# set defaults. These will be replaced if there are entries for them
|
# set defaults. These will be replaced if there are entries for them
|
||||||
@ -230,7 +289,11 @@ class CFFFontSet(object):
|
|||||||
self.minor = int(attrs['value'])
|
self.minor = int(attrs['value'])
|
||||||
|
|
||||||
def convertCFFToCFF2(self, otFont):
|
def convertCFFToCFF2(self, otFont):
|
||||||
# This assumes a decompiled CFF table.
|
"""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 :meth:`decompile`.)"""
|
||||||
self.major = 2
|
self.major = 2
|
||||||
cff2GetGlyphOrder = self.otFont.getGlyphOrder
|
cff2GetGlyphOrder = self.otFont.getGlyphOrder
|
||||||
topDictData = TopDictIndex(None, cff2GetGlyphOrder, None)
|
topDictData = TopDictIndex(None, cff2GetGlyphOrder, None)
|
||||||
@ -307,7 +370,8 @@ class CFFFontSet(object):
|
|||||||
|
|
||||||
|
|
||||||
class CFFWriter(object):
|
class CFFWriter(object):
|
||||||
|
"""Helper class for serializing CFF data to binary. Used by
|
||||||
|
:meth:`CFFFontSet.compile`."""
|
||||||
def __init__(self, isCFF2):
|
def __init__(self, isCFF2):
|
||||||
self.data = []
|
self.data = []
|
||||||
self.isCFF2 = isCFF2
|
self.isCFF2 = isCFF2
|
||||||
@ -367,6 +431,8 @@ def calcOffSize(largestOffset):
|
|||||||
|
|
||||||
|
|
||||||
class IndexCompiler(object):
|
class IndexCompiler(object):
|
||||||
|
"""Base class for writing CFF `INDEX data <https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#5-index-data>`_
|
||||||
|
to binary."""
|
||||||
|
|
||||||
def __init__(self, items, strings, parent, isCFF2=None):
|
def __init__(self, items, strings, parent, isCFF2=None):
|
||||||
if isCFF2 is None and hasattr(parent, "isCFF2"):
|
if isCFF2 is None and hasattr(parent, "isCFF2"):
|
||||||
@ -446,6 +512,7 @@ class IndexedStringsCompiler(IndexCompiler):
|
|||||||
|
|
||||||
|
|
||||||
class TopDictIndexCompiler(IndexCompiler):
|
class TopDictIndexCompiler(IndexCompiler):
|
||||||
|
"""Helper class for writing the TopDict to binary."""
|
||||||
|
|
||||||
def getItems(self, items, strings):
|
def getItems(self, items, strings):
|
||||||
out = []
|
out = []
|
||||||
@ -481,6 +548,9 @@ class TopDictIndexCompiler(IndexCompiler):
|
|||||||
|
|
||||||
|
|
||||||
class FDArrayIndexCompiler(IndexCompiler):
|
class FDArrayIndexCompiler(IndexCompiler):
|
||||||
|
"""Helper class for writing the
|
||||||
|
`Font DICT INDEX <https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#10-font-dict-index-font-dicts-and-fdselect>`_
|
||||||
|
to binary."""
|
||||||
|
|
||||||
def getItems(self, items, strings):
|
def getItems(self, items, strings):
|
||||||
out = []
|
out = []
|
||||||
@ -519,6 +589,8 @@ class FDArrayIndexCompiler(IndexCompiler):
|
|||||||
|
|
||||||
|
|
||||||
class GlobalSubrsCompiler(IndexCompiler):
|
class GlobalSubrsCompiler(IndexCompiler):
|
||||||
|
"""Helper class for writing the `global subroutine INDEX <https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#9-local-and-global-subr-indexes>`_
|
||||||
|
to binary."""
|
||||||
|
|
||||||
def getItems(self, items, strings):
|
def getItems(self, items, strings):
|
||||||
out = []
|
out = []
|
||||||
@ -529,6 +601,8 @@ class GlobalSubrsCompiler(IndexCompiler):
|
|||||||
|
|
||||||
|
|
||||||
class SubrsCompiler(GlobalSubrsCompiler):
|
class SubrsCompiler(GlobalSubrsCompiler):
|
||||||
|
"""Helper class for writing the `local subroutine INDEX <https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#9-local-and-global-subr-indexes>`_
|
||||||
|
to binary."""
|
||||||
|
|
||||||
def setPos(self, pos, endPos):
|
def setPos(self, pos, endPos):
|
||||||
offset = pos - self.parent.pos
|
offset = pos - self.parent.pos
|
||||||
@ -536,7 +610,8 @@ class SubrsCompiler(GlobalSubrsCompiler):
|
|||||||
|
|
||||||
|
|
||||||
class CharStringsCompiler(GlobalSubrsCompiler):
|
class CharStringsCompiler(GlobalSubrsCompiler):
|
||||||
|
"""Helper class for writing the `CharStrings INDEX <https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#9-local-and-global-subr-indexes>`_
|
||||||
|
to binary."""
|
||||||
def getItems(self, items, strings):
|
def getItems(self, items, strings):
|
||||||
out = []
|
out = []
|
||||||
for cs in items:
|
for cs in items:
|
||||||
@ -549,8 +624,9 @@ class CharStringsCompiler(GlobalSubrsCompiler):
|
|||||||
|
|
||||||
|
|
||||||
class Index(object):
|
class Index(object):
|
||||||
|
"""This class represents what the CFF spec calls an INDEX (an array of
|
||||||
"""This class represents what the CFF spec calls an INDEX."""
|
variable-sized objects). `Index` items can be addressed and set using
|
||||||
|
Python list indexing."""
|
||||||
|
|
||||||
compilerClass = IndexCompiler
|
compilerClass = IndexCompiler
|
||||||
|
|
||||||
@ -608,16 +684,50 @@ class Index(object):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def append(self, item):
|
def append(self, item):
|
||||||
|
"""Add an item to an INDEX."""
|
||||||
self.items.append(item)
|
self.items.append(item)
|
||||||
|
|
||||||
def getCompiler(self, strings, parent, isCFF2=None):
|
def getCompiler(self, strings, parent, isCFF2=None):
|
||||||
return self.compilerClass(self, strings, parent, isCFF2=isCFF2)
|
return self.compilerClass(self, strings, parent, isCFF2=isCFF2)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
"""Empty the INDEX."""
|
||||||
del self.items[:]
|
del self.items[:]
|
||||||
|
|
||||||
|
|
||||||
class GlobalSubrsIndex(Index):
|
class GlobalSubrsIndex(Index):
|
||||||
|
"""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:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
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>`)
|
||||||
|
"""
|
||||||
|
|
||||||
compilerClass = GlobalSubrsCompiler
|
compilerClass = GlobalSubrsCompiler
|
||||||
subrClass = psCharStrings.T2CharString
|
subrClass = psCharStrings.T2CharString
|
||||||
@ -647,6 +757,15 @@ class GlobalSubrsIndex(Index):
|
|||||||
return self.subrClass(data, private=private, globalSubrs=self.globalSubrs)
|
return self.subrClass(data, private=private, globalSubrs=self.globalSubrs)
|
||||||
|
|
||||||
def toXML(self, xmlWriter):
|
def toXML(self, xmlWriter):
|
||||||
|
"""Write the subroutines index into XML representation onto the given
|
||||||
|
:class:`fontTools.misc.xmlWriter.XMLWriter`.
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
writer = xmlWriter.XMLWriter(sys.stdout)
|
||||||
|
tt["CFF "].cff[0].GlobalSubrs.toXML(writer)
|
||||||
|
|
||||||
|
"""
|
||||||
xmlWriter.comment(
|
xmlWriter.comment(
|
||||||
"The 'index' attribute is only for humans; "
|
"The 'index' attribute is only for humans; "
|
||||||
"it is ignored when parsed.")
|
"it is ignored when parsed.")
|
||||||
@ -677,10 +796,26 @@ class GlobalSubrsIndex(Index):
|
|||||||
|
|
||||||
|
|
||||||
class SubrsIndex(GlobalSubrsIndex):
|
class SubrsIndex(GlobalSubrsIndex):
|
||||||
|
"""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."""
|
||||||
|
|
||||||
compilerClass = SubrsCompiler
|
compilerClass = SubrsCompiler
|
||||||
|
|
||||||
|
|
||||||
class TopDictIndex(Index):
|
class TopDictIndex(Index):
|
||||||
|
"""This index represents the array of ``TopDict`` structures in the font
|
||||||
|
(again, usually only one entry is present). Hence the following calls are
|
||||||
|
equivalent:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
tt["CFF "].cff[0]
|
||||||
|
# <fontTools.cffLib.TopDict object at 0x102ed6e50>
|
||||||
|
tt["CFF "].cff.topDictIndex[0]
|
||||||
|
# <fontTools.cffLib.TopDict object at 0x102ed6e50>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
compilerClass = TopDictIndexCompiler
|
compilerClass = TopDictIndexCompiler
|
||||||
|
|
||||||
@ -869,6 +1004,20 @@ class FDSelect(object):
|
|||||||
|
|
||||||
|
|
||||||
class CharStrings(object):
|
class CharStrings(object):
|
||||||
|
"""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:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
tt["CFF "].cff[0].CharStrings["a"]
|
||||||
|
# <T2CharString (bytecode) at 103451e90>
|
||||||
|
|
||||||
|
See :class:`fontTools.misc.psCharStrings.T1CharString` and
|
||||||
|
:class:`fontTools.misc.psCharStrings.T2CharString` for how to decompile,
|
||||||
|
compile and interpret the glyph drawing instructions in the returned objects.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, file, charset, globalSubrs, private, fdSelect, fdArray,
|
def __init__(self, file, charset, globalSubrs, private, fdSelect, fdArray,
|
||||||
isCFF2=None):
|
isCFF2=None):
|
||||||
@ -2087,27 +2236,33 @@ class DictCompiler(object):
|
|||||||
|
|
||||||
|
|
||||||
def arg_delta_blend(self, value):
|
def arg_delta_blend(self, value):
|
||||||
""" A delta list with blend lists has to be *all* blend lists.
|
"""A delta list with blend lists has to be *all* blend lists.
|
||||||
The value is a list is arranged as follows.
|
|
||||||
[
|
The value is a list is arranged as follows::
|
||||||
[V0, d0..dn]
|
|
||||||
[V1, d0..dn]
|
[
|
||||||
...
|
[V0, d0..dn]
|
||||||
[Vm, d0..dn]
|
[V1, d0..dn]
|
||||||
]
|
...
|
||||||
V is the absolute coordinate value from the default font, and d0-dn are
|
[Vm, d0..dn]
|
||||||
the delta values from the n regions. Each V is an absolute coordinate
|
]
|
||||||
from the default font.
|
|
||||||
We want to return a list:
|
``V`` is the absolute coordinate value from the default font, and ``d0-dn``
|
||||||
[
|
are the delta values from the *n* regions. Each ``V`` is an absolute
|
||||||
[v0, v1..vm]
|
coordinate from the default font.
|
||||||
[d0..dn]
|
|
||||||
...
|
We want to return a list::
|
||||||
[d0..dn]
|
|
||||||
numBlends
|
[
|
||||||
blendOp
|
[v0, v1..vm]
|
||||||
]
|
[d0..dn]
|
||||||
where each v is relative to the previous default font value.
|
...
|
||||||
|
[d0..dn]
|
||||||
|
numBlends
|
||||||
|
blendOp
|
||||||
|
]
|
||||||
|
|
||||||
|
where each ``v`` is relative to the previous default font value.
|
||||||
"""
|
"""
|
||||||
numMasters = len(value[0])
|
numMasters = len(value[0])
|
||||||
numBlends = len(value)
|
numBlends = len(value)
|
||||||
@ -2356,6 +2511,30 @@ class BaseDict(object):
|
|||||||
|
|
||||||
|
|
||||||
class TopDict(BaseDict):
|
class TopDict(BaseDict):
|
||||||
|
"""The ``TopDict`` represents the top-level dictionary holding font
|
||||||
|
information. CFF2 tables contain a restricted set of top-level entries
|
||||||
|
as described `here <https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#7-top-dict-data>`_,
|
||||||
|
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:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
tt["CFF "].cff[0].Private.BlueValues
|
||||||
|
# [-15, 0, 515, 515, 666, 666]
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
defaults = buildDefaults(topDictOperators)
|
defaults = buildDefaults(topDictOperators)
|
||||||
converters = buildConverters(topDictOperators)
|
converters = buildConverters(topDictOperators)
|
||||||
@ -2377,6 +2556,7 @@ class TopDict(BaseDict):
|
|||||||
self.order = buildOrder(topDictOperators)
|
self.order = buildOrder(topDictOperators)
|
||||||
|
|
||||||
def getGlyphOrder(self):
|
def getGlyphOrder(self):
|
||||||
|
"""Returns a list of glyph names in the CFF font."""
|
||||||
return self.charset
|
return self.charset
|
||||||
|
|
||||||
def postDecompile(self):
|
def postDecompile(self):
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""T2CharString operator specializer and generalizer."""
|
"""T2CharString operator specializer and generalizer.
|
||||||
|
|
||||||
|
PostScript glyph drawing operations can be expressed in multiple different
|
||||||
|
ways. For example, as well as the ``lineto`` operator, there is also a
|
||||||
|
``hlineto`` operator which draws a horizontal line, removing the need to
|
||||||
|
specify a ``dx`` coordinate, and a ``vlineto`` operator which draws a
|
||||||
|
vertical line, removing the need to specify a ``dy`` coordinate. As well
|
||||||
|
as decompiling :class:`fontTools.misc.psCharStrings.T2CharString` objects
|
||||||
|
into lists of operations, this module allows for conversion between general
|
||||||
|
and specific forms of the operation.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.cffLib import maxStackLimit
|
from fontTools.cffLib import maxStackLimit
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""T2CharString glyph width optimizer."""
|
"""T2CharString glyph width optimizer.
|
||||||
|
|
||||||
|
CFF glyphs whose width equals the CFF Private dictionary's ``defaultWidthX``
|
||||||
|
value do not need to specify their width in their charstring, saving bytes.
|
||||||
|
This module determines the optimum ``defaultWidthX`` and ``nominalWidthX``
|
||||||
|
values for a font, when provided with a list of glyph widths."""
|
||||||
|
|
||||||
from fontTools.misc.py23 import *
|
from fontTools.misc.py23 import *
|
||||||
from fontTools.ttLib import TTFont, getTableClass
|
from fontTools.ttLib import TTFont, getTableClass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user