This commit is contained in:
Khaled Hosny 2024-02-06 15:47:35 +02:00
parent ed1ffafe44
commit cf08265cd5
64 changed files with 98 additions and 110 deletions

View File

@ -45,7 +45,6 @@ Here is an example of using `afmLib` to read, modify and write an AFM file:
"""
import re
# every single line starts with a "word"

View File

@ -2880,7 +2880,6 @@ class PrivateDict(BaseDict):
class IndexedStrings(object):
"""SID -> string mapping."""
def __init__(self, file=None):

View File

@ -2,6 +2,7 @@
colorLib.builder: Build COLR/CPAL tables from scratch
"""
import collections
import copy
import enum
@ -298,11 +299,15 @@ def buildPaletteLabels(
labels: Iterable[_OptionalLocalizedString], nameTable: _n_a_m_e.table__n_a_m_e
) -> List[Optional[int]]:
return [
(
nameTable.addMultilingualName(l, mac=False)
if isinstance(l, dict)
else C_P_A_L_.table_C_P_A_L_.NO_NAME_ID
else (
C_P_A_L_.table_C_P_A_L_.NO_NAME_ID
if l is None
else nameTable.addMultilingualName({"en": l}, mac=False)
)
)
for l in labels
]

View File

@ -6,6 +6,7 @@ etc. If this file gets too big, split it into smaller files per-module.
An instance of the Config class can be attached to a TTFont object, so that
the various modules can access their configuration options from it.
"""
from textwrap import dedent
from fontTools.misc.configTools import *

View File

@ -1413,9 +1413,9 @@ class BaseDocWriter(object):
):
axesElement = ET.Element("axes")
if self.documentObject.elidedFallbackName is not None:
axesElement.attrib[
"elidedfallbackname"
] = self.documentObject.elidedFallbackName
axesElement.attrib["elidedfallbackname"] = (
self.documentObject.elidedFallbackName
)
self.root.append(axesElement)
for axisObject in self.documentObject.axes:
self._addAxis(axisObject)
@ -1744,17 +1744,17 @@ class BaseDocWriter(object):
if instanceObject.filename is not None:
instanceElement.attrib["filename"] = instanceObject.filename
if instanceObject.postScriptFontName is not None:
instanceElement.attrib[
"postscriptfontname"
] = instanceObject.postScriptFontName
instanceElement.attrib["postscriptfontname"] = (
instanceObject.postScriptFontName
)
if instanceObject.styleMapFamilyName is not None:
instanceElement.attrib[
"stylemapfamilyname"
] = instanceObject.styleMapFamilyName
instanceElement.attrib["stylemapfamilyname"] = (
instanceObject.styleMapFamilyName
)
if instanceObject.styleMapStyleName is not None:
instanceElement.attrib[
"stylemapstylename"
] = instanceObject.styleMapStyleName
instanceElement.attrib["stylemapstylename"] = (
instanceObject.styleMapStyleName
)
if self.effectiveFormatTuple < (5, 0):
# Deprecated members as of version 5.0
if instanceObject.glyphs:

View File

@ -8,6 +8,7 @@ instance:
names = getStatNames(doc, instance.getFullUserLocation(doc))
print(names.styleNames)
"""
from __future__ import annotations
from dataclasses import dataclass

View File

@ -169,20 +169,16 @@ otTables.BaseTagList.mergeMap = {
"BaselineTag": sumLists,
}
otTables.GDEF.mergeMap = (
otTables.GSUB.mergeMap
) = (
otTables.GPOS.mergeMap
) = otTables.BASE.mergeMap = otTables.JSTF.mergeMap = otTables.MATH.mergeMap = {
otTables.GDEF.mergeMap = otTables.GSUB.mergeMap = otTables.GPOS.mergeMap = (
otTables.BASE.mergeMap
) = otTables.JSTF.mergeMap = otTables.MATH.mergeMap = {
"*": mergeObjects,
"Version": max,
}
ttLib.getTableClass("GDEF").mergeMap = ttLib.getTableClass(
"GSUB"
).mergeMap = ttLib.getTableClass("GPOS").mergeMap = ttLib.getTableClass(
"BASE"
).mergeMap = ttLib.getTableClass(
ttLib.getTableClass("GDEF").mergeMap = ttLib.getTableClass("GSUB").mergeMap = (
ttLib.getTableClass("GPOS").mergeMap
) = ttLib.getTableClass("BASE").mergeMap = ttLib.getTableClass(
"JSTF"
).mergeMap = ttLib.getTableClass(
"MATH"

View File

@ -3,7 +3,6 @@
class Classifier(object):
"""
Main Classifier object, used to classify things into similar sets.
"""

View File

@ -1,4 +1,5 @@
"""Collection of utilities for command-line interfaces and console scripts."""
import os
import re

View File

@ -8,6 +8,7 @@ To create your own config system, you need to create an instance of
``options`` class variable set to your instance of Options.
"""
from __future__ import annotations
import logging

View File

@ -1,6 +1,5 @@
"""Misc dict tools."""
__all__ = ["hashdict"]

View File

@ -11,6 +11,7 @@ or subclasses built-in ElementTree classes to add features that are
only availble in lxml, like OrderedDict for attributes, pretty_print and
iterwalk.
"""
from fontTools.misc.textTools import tostr

View File

@ -17,7 +17,6 @@ by Tal Leming and is copyright (c) 2005-2016, The RoboFab Developers:
- Just van Rossum
"""
illegalCharacters = r"\" * + / : < > ? [ \ ] | \0".split(" ")
illegalCharacters += [chr(i) for i in range(1, 32)]
illegalCharacters += [chr(0x7F)]

View File

@ -1,6 +1,5 @@
"""fontTools.misc.textTools.py -- miscellaneous routines."""
import ast
import string

View File

@ -76,7 +76,6 @@ def _normSinCos(v):
class Transform(NamedTuple):
"""2x2 transformation matrix plus offset, a.k.a. Affine transform.
Transform instances are immutable: all transforming methods, eg.
rotate(), return a new Transform instance.

View File

@ -8,7 +8,6 @@ __all__ = ["Vector"]
class Vector(tuple):
"""A math-like vector.
Represents an n-dimensional numeric vector. ``Vector`` objects support

View File

@ -148,7 +148,6 @@ class AbstractPen:
class NullPen(AbstractPen):
"""A pen that does nothing."""
def moveTo(self, pt):
@ -187,7 +186,6 @@ class MissingComponentError(KeyError):
class DecomposingPen(LoggingPen):
"""Implements a 'addComponent' method that decomposes components
(i.e. draws them onto self as simple contours).
It can also be used as a mixin class (e.g. see ContourRecordingPen).
@ -229,7 +227,6 @@ class DecomposingPen(LoggingPen):
class BasePen(DecomposingPen):
"""Base class for drawing pens. You must override _moveTo, _lineTo and
_curveToOne. You may additionally override _closePath, _endPath,
addComponent, addVarComponent, and/or _qCurveToOne. You should not

View File

@ -7,7 +7,6 @@ __all__ = ["BoundsPen", "ControlBoundsPen"]
class ControlBoundsPen(BasePen):
"""Pen to calculate the "control bounds" of a shape. This is the
bounding box of all control points, so may be larger than the
actual bounding box if there are curves that don't have points
@ -67,7 +66,6 @@ class ControlBoundsPen(BasePen):
class BoundsPen(ControlBoundsPen):
"""Pen to calculate the bounds of a shape. It calculates the
correct bounds even when the shape contains curves that don't
have points on their extremes. This is somewhat slower to compute

View File

@ -9,7 +9,6 @@ class _PassThruComponentsMixin(object):
class FilterPen(_PassThruComponentsMixin, AbstractPen):
"""Base class for pens that apply some transformation to the coordinates
they receive and pass them to another pen.

View File

@ -10,7 +10,6 @@ __all__ = ["PointInsidePen"]
class PointInsidePen(BasePen):
"""This pen implements "point inside" testing: to test whether
a given point lies inside the shape (black) or outside (white).
Instances of this class can be recycled, as long as the

View File

@ -9,7 +9,6 @@ __all__ = ["QuartzPen"]
class QuartzPen(BasePen):
"""A pen that creates a CGPath
Parameters

View File

@ -1,4 +1,5 @@
"""Pen recording operations that can be accessed or replayed."""
from fontTools.pens.basePen import AbstractPen, DecomposingPen
from fontTools.pens.pointPen import AbstractPointPen

View File

@ -6,7 +6,6 @@ __all__ = ["ReportLabPen"]
class ReportLabPen(BasePen):
"""A pen for drawing onto a ``reportlab.graphics.shapes.Path`` object."""
def __init__(self, glyphSet, path=None):

View File

@ -1,5 +1,6 @@
"""Pen calculating area, center of mass, variance and standard-deviation,
covariance and correlation, and slant, of glyph shapes."""
from math import sqrt, degrees, atan
from fontTools.pens.basePen import BasePen, OpenContourError
from fontTools.pens.momentsPen import MomentsPen
@ -52,7 +53,6 @@ class StatisticsBase:
class StatisticsPen(StatisticsBase, MomentsPen):
"""Pen calculating area, center of mass, variance and
standard-deviation, covariance and correlation, and slant,
of glyph shapes.
@ -91,7 +91,6 @@ class StatisticsPen(StatisticsBase, MomentsPen):
class StatisticsControlPen(StatisticsBase, BasePen):
"""Pen calculating area, center of mass, variance and
standard-deviation, covariance and correlation, and slant,
of glyph shapes, using the control polygon only.

View File

@ -1,4 +1,5 @@
"""Pen multiplexing drawing to one or more pens."""
from fontTools.pens.basePen import AbstractPen

View File

@ -5,7 +5,6 @@ __all__ = ["TransformPen", "TransformPointPen"]
class TransformPen(FilterPen):
"""Pen that transforms all coordinates using a Affine transformation,
and passes them to another pen.
"""

View File

@ -4,6 +4,7 @@ The code is mostly adapted from Blink's SVGPathNormalizer::DecomposeArcToCubic
https://github.com/chromium/chromium/blob/93831f2/third_party/
blink/renderer/core/svg/svg_path_parser.cc#L169-L278
"""
from fontTools.misc.transform import Identity, Scale
from math import atan2, ceil, cos, fabs, isfinite, pi, radians, sin, sqrt, tan

View File

@ -15,6 +15,7 @@ write(path, data, kind='OTHER', dohex=False)
part should be written as hexadecimal or binary, but only if kind
is 'OTHER'.
"""
import fontTools
from fontTools.misc import eexec
from fontTools.misc.macCreatorType import getMacCreatorAndType
@ -49,7 +50,6 @@ class T1Error(Exception):
class T1Font(object):
"""Type 1 font class.
Uses a minimal interpeter that supports just about enough PS to parse

View File

@ -1,4 +1,5 @@
"""ttLib.macUtils.py -- Various Mac-specific stuff."""
from io import BytesIO
from fontTools.misc.macRes import ResourceReader, ResourceError
@ -35,7 +36,6 @@ def openTTFonts(path):
class SFNTResourceReader(BytesIO):
"""Simple read-only file wrapper for 'sfnt' resources."""
def __init__(self, path, res_name_or_index):

View File

@ -202,9 +202,11 @@ def removeOverlaps(
glyphNames = sorted(
glyphNames,
key=lambda name: (
(
glyfTable[name].getCompositeMaxpValues(glyfTable).maxComponentDepth
if glyfTable[name].isComposite()
else 0,
else 0
),
name,
),
)

View File

@ -3,7 +3,6 @@
AAT and Graphite tables are not supported. CFF/CFF2 fonts
are de-subroutinized."""
from fontTools.ttLib.ttVisitor import TTVisitor
import fontTools.ttLib as ttLib
import fontTools.ttLib.tables.otBase as otBase

View File

@ -7,7 +7,6 @@ from . import DefaultTable
class table_C_O_L_R_(DefaultTable.DefaultTable):
"""This table is structured so that you can treat it like a dictionary keyed by glyph name.
``ttFont['COLR'][<glyphName>]`` will return the color layers for any glyph.

View File

@ -113,7 +113,6 @@ OS2_format_5_addition = bigendian + OS2_format_5_addition
class table_O_S_2f_2(DefaultTable.DefaultTable):
"""the OS/2 table"""
dependencies = ["head"]

View File

@ -5,6 +5,7 @@ TSI0 is the index table containing the lengths and offsets for the glyph
programs and 'extra' programs ('fpgm', 'prep', and 'cvt') that are contained
in the TSI1 table.
"""
from . import DefaultTable
import struct

View File

@ -4,6 +4,7 @@ tool to store its hinting source data.
TSI1 contains the text of the glyph programs in the form of low-level assembly
code, as well as the 'extra' programs 'fpgm', 'ppgm' (i.e. 'prep'), and 'cvt'.
"""
from . import DefaultTable
from fontTools.misc.loggingTools import LogMixin
from fontTools.misc.textTools import strjoin, tobytes, tostr

View File

@ -5,6 +5,7 @@ TSI2 is the index table containing the lengths and offsets for the glyph
programs that are contained in the TSI3 table. It uses the same format as
the TSI0 table.
"""
from fontTools import ttLib
superclass = ttLib.getTableClass("TSI0")

View File

@ -3,6 +3,7 @@ tool to store its hinting source data.
TSI3 contains the text of the glyph programs in the form of 'VTTTalk' code.
"""
from fontTools import ttLib
superclass = ttLib.getTableClass("TSI1")

View File

@ -3,6 +3,7 @@ tool to store its hinting source data.
TSI5 contains the VTT character groups.
"""
from fontTools.misc.textTools import safeEval
from . import DefaultTable
import sys

View File

@ -517,22 +517,22 @@ class TupleVariation(object):
return # no change
coordWidth = self.getCoordWidth()
self.coordinates = [
(
None
if d is None
else d * scalar
if coordWidth == 1
else (d[0] * scalar, d[1] * scalar)
else d * scalar if coordWidth == 1 else (d[0] * scalar, d[1] * scalar)
)
for d in self.coordinates
]
def roundDeltas(self):
coordWidth = self.getCoordWidth()
self.coordinates = [
(
None
if d is None
else otRound(d)
if coordWidth == 1
else (otRound(d[0]), otRound(d[1]))
else otRound(d) if coordWidth == 1 else (otRound(d[0]), otRound(d[1]))
)
for d in self.coordinates
]

View File

@ -4,7 +4,6 @@ import struct
class table_V_O_R_G_(DefaultTable.DefaultTable):
"""This table is structured so that you can treat it like a dictionary keyed by glyph name.
``ttFont['VORG'][<glyphName>]`` will return the vertical origin for any glyph.

View File

@ -147,9 +147,9 @@ class KernTable_format_0(object):
except IndexError:
# Slower, but will not throw an IndexError on an invalid
# glyph id.
kernTable[
(ttFont.getGlyphName(left), ttFont.getGlyphName(right))
] = value
kernTable[(ttFont.getGlyphName(left), ttFont.getGlyphName(right))] = (
value
)
if len(data) > 6 * nPairs + 4: # Ignore up to 4 bytes excess
log.warning(
"excess data in 'kern' subtable: %d bytes", len(data) - 6 * nPairs

View File

@ -79,7 +79,6 @@ class RepackerState(IntEnum):
class BaseTTXConverter(DefaultTable):
"""Generic base class for TTX table converters. It functions as an
adapter between the TTX (ttLib actually) table model and the model
we use for OpenType tables, which is necessarily subtly different.
@ -260,7 +259,6 @@ assert array.array("i").itemsize == 4, "Oops, file a bug against fonttools."
class OTTableReader(object):
"""Helper class to retrieve data from an OpenType table."""
__slots__ = ("data", "offset", "pos", "localState", "tableTag")
@ -392,7 +390,6 @@ class OffsetToWriter(object):
class OTTableWriter(object):
"""Helper class to gather and assemble data for OpenType tables."""
def __init__(self, localState=None, tableTag=None):
@ -882,7 +879,6 @@ def packUInt24(value):
class BaseTable(object):
"""Generic base class for all OpenType (sub)tables."""
def __getattr__(self, attr):
@ -1210,7 +1206,6 @@ class BaseTable(object):
class FormatSwitchingBaseTable(BaseTable):
"""Minor specialization of BaseTable, for tables that have multiple
formats, eg. CoverageFormat1 vs. CoverageFormat2."""
@ -1335,7 +1330,6 @@ valueRecordFormatDict = _buildDict()
class ValueRecordFactory(object):
"""Given a format code, this object convert ValueRecords."""
def __init__(self, valueFormat):

View File

@ -146,7 +146,6 @@ class _LazyList(UserList):
class BaseConverter(object):
"""Base class for converter objects. Apart from the constructor, this
is an abstract class."""

View File

@ -1,4 +1,5 @@
"""Methods for traversing trees of otData-driven OpenType tables."""
from collections import deque
from typing import Callable, Deque, Iterable, List, Optional, Tuple
from .otBase import BaseTable

View File

@ -1,4 +1,5 @@
"""ttLib.tables.ttProgram.py -- Assembler/disassembler for TrueType bytecode programs."""
from __future__ import annotations
from fontTools.misc.textTools import num2binary, binary2num, readHex, strjoin

View File

@ -8,7 +8,6 @@ log = logging.getLogger(__name__)
class TTCollection(object):
"""Object representing a TrueType Collection / OpenType Collection.
The main API is self.fonts being a list of TTFont instances.

View File

@ -15,7 +15,6 @@ log = logging.getLogger(__name__)
class TTFont(object):
"""Represents a TrueType font.
The object manages file input and output, and offers a convenient way of
@ -843,7 +842,6 @@ class TTFont(object):
class GlyphOrder(object):
"""A pseudo table. The glyph order isn't in the font as a separate
table, but it's nice to present it as such in the TTX format.
"""

View File

@ -17,7 +17,6 @@ from fontTools.pens.recordingPen import (
class _TTGlyphSet(Mapping):
"""Generic dict-like GlyphSet class that pulls metrics from hmtx and
glyph shape from TrueType or CFF.
"""
@ -125,7 +124,6 @@ class _TTGlyphSetCFF(_TTGlyphSet):
class _TTGlyph(ABC):
"""Glyph object that supports the Pen protocol, meaning that it has
.draw() and .drawPoints() methods that take a pen object as their only
argument. Additionally there are 'width' and 'lsb' attributes, read from

View File

@ -103,7 +103,6 @@ Compile options
extension is available at https://pypi.python.org/pypi/zopfli
"""
from fontTools.ttLib import TTFont, TTLibError
from fontTools.misc.macCreatorType import getMacCreatorAndType
from fontTools.unicode import setUnicodeData

View File

@ -197,7 +197,6 @@ class _UFOBaseIO:
class UFOReader(_UFOBaseIO):
"""
Read the various components of the .ufo.
@ -881,7 +880,6 @@ class UFOReader(_UFOBaseIO):
class UFOWriter(UFOReader):
"""
Write the various components of the .ufo.

View File

@ -2,7 +2,6 @@
Conversion functions.
"""
# adapted from the UFO spec

View File

@ -2,4 +2,5 @@
for the old ufoLib.etree module, which was moved to fontTools.misc.etree.
Please use the latter instead.
"""
from fontTools.misc.etree import *

View File

@ -91,7 +91,6 @@ GLIFFormatVersion.__str__ = _VersionTupleEnumMixin.__str__
class Glyph:
"""
Minimal glyph object. It has no glyph attributes until either
the draw() or the drawPoints() method has been called.
@ -123,7 +122,6 @@ class Glyph:
class GlyphSet(_UFOBaseIO):
"""
GlyphSet manages a set of .glif files inside one directory.
@ -1228,9 +1226,9 @@ def _readGlyphFromTreeFormat2(
unicodes = []
guidelines = []
anchors = []
haveSeenAdvance = (
haveSeenImage
) = haveSeenOutline = haveSeenLib = haveSeenNote = False
haveSeenAdvance = haveSeenImage = haveSeenOutline = haveSeenLib = haveSeenNote = (
False
)
identifiers = set()
for element in tree:
if element.tag == "outline":
@ -1883,7 +1881,6 @@ _transformationInfo = [
class GLIFPointPen(AbstractPointPen):
"""
Helper class using the PointPen protocol to write the <outline>
part of .glif files.

View File

@ -2,6 +2,7 @@
for the old ufoLib.plistlib module, which was moved to fontTools.misc.plistlib.
Please use the latter instead.
"""
from fontTools.misc.plistlib import dump, dumps, load, loads
from fontTools.misc.textTools import tobytes

View File

@ -2,4 +2,5 @@
for the old ufoLib.pointPen module, which was moved to fontTools.pens.pointPen.
Please use the latter instead.
"""
from fontTools.pens.pointPen import *

View File

@ -1,6 +1,7 @@
"""The module contains miscellaneous helpers.
It's not considered part of the public ufoLib API.
"""
import warnings
import functools

View File

@ -201,15 +201,13 @@ T = TypeVar("T")
@overload
def script_horizontal_direction(script_code: str, default: T) -> HorizDirection | T:
...
def script_horizontal_direction(script_code: str, default: T) -> HorizDirection | T: ...
@overload
def script_horizontal_direction(
script_code: str, default: type[KeyError] = KeyError
) -> HorizDirection:
...
) -> HorizDirection: ...
def script_horizontal_direction(

View File

@ -18,6 +18,7 @@ Then you can make a variable-font this way:
API *will* change in near future.
"""
from typing import List
from fontTools.misc.vector import Vector
from fontTools.misc.roundTools import noRound, otRound
@ -569,9 +570,11 @@ def _get_advance_metrics(
sparse_advance = 0xFFFF
for glyph in glyphOrder:
vhAdvances = [
(
metrics[glyph][0]
if glyph in metrics and metrics[glyph][0] != sparse_advance
else None
)
for metrics in advMetricses
]
vhAdvanceDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports(

View File

@ -3,6 +3,7 @@ https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariat
NOTE: The API is experimental and subject to change.
"""
from fontTools.misc.dictTools import hashdict
from fontTools.misc.intTools import bit_count
from fontTools.ttLib import newTable

View File

@ -82,6 +82,7 @@ are supported, but support for CFF2 variable fonts will be added soon.
The discussion and implementation of these features are tracked at
https://github.com/fonttools/fonttools/issues/1537
"""
from fontTools.misc.fixedTools import (
floatToFixedToFloat,
strToFixedToFloat,
@ -643,9 +644,11 @@ def instantiateGvar(varfont, axisLimits, optimize=True):
glyphnames = sorted(
glyf.glyphOrder,
key=lambda name: (
(
glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth
if glyf[name].isComposite() or glyf[name].isVarComposite()
else 0,
else 0
),
name,
),
)

View File

@ -1,6 +1,7 @@
"""
Interpolate OpenType Layout tables (GDEF / GPOS / GSUB).
"""
from fontTools.ttLib import TTFont
from fontTools.varLib import models, VarLibError, load_designspace, load_masters
from fontTools.varLib.merger import InstancerMerger

View File

@ -1,6 +1,7 @@
"""
Merge OpenType Layout tables (GDEF / GPOS / GSUB).
"""
import os
import copy
import enum

View File

@ -3,6 +3,7 @@ Instantiate a variation font. Run, eg:
$ fonttools varLib.mutator ./NotoSansArabic-VF.ttf wght=140 wdth=85
"""
from fontTools.misc.fixedTools import floatToFixedToFloat, floatToFixed
from fontTools.misc.roundTools import otRound
from fontTools.pens.boundsPen import BoundsPen
@ -198,9 +199,11 @@ def instantiateVariableFont(varfont, location, inplace=False, overlap=True):
glyphnames = sorted(
gvar.variations.keys(),
key=lambda name: (
(
glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth
if glyf[name].isComposite() or glyf[name].isVarComposite()
else 0,
else 0
),
name,
),
)
@ -304,9 +307,9 @@ def instantiateVariableFont(varfont, location, inplace=False, overlap=True):
if applies:
assert record.FeatureTableSubstitution.Version == 0x00010000
for rec in record.FeatureTableSubstitution.SubstitutionRecord:
table.FeatureList.FeatureRecord[
rec.FeatureIndex
].Feature = rec.Feature
table.FeatureList.FeatureRecord[rec.FeatureIndex].Feature = (
rec.Feature
)
break
del table.FeatureVariations

View File

@ -46,9 +46,7 @@ env_with_cython = os.environ.get("FONTTOOLS_WITH_CYTHON")
with_cython = (
True
if env_with_cython in {"1", "true", "yes"}
else False
if env_with_cython in {"0", "false", "no"}
else None
else False if env_with_cython in {"0", "false", "no"} else None
)
# --with-cython/--without-cython options override environment variables
opt_with_cython = {"--with-cython"}.intersection(sys.argv)