Skip to content

Commit

Permalink
move parsing public.openTypeCategories to util module
Browse files Browse the repository at this point in the history
  • Loading branch information
anthrotype committed Jan 23, 2024
1 parent db583e3 commit 5cc53e2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 44 deletions.
44 changes: 2 additions & 42 deletions Lib/ufo2ft/featureWriters/baseFeatureWriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from fontTools.feaLib.variableScalar import VariableScalar
from fontTools.misc.fixedTools import otRound

from ufo2ft.constants import OPENTYPE_CATEGORIES_KEY
from ufo2ft.errors import InvalidFeaturesData
from ufo2ft.featureWriters import ast
from ufo2ft.util import (
OpenTypeCategories,
collapse_varscalar,
get_userspace_location,
quantize,
Expand Down Expand Up @@ -351,47 +351,7 @@ def extraSubstitutions(self):
def getOpenTypeCategories(self):
"""Return 'public.openTypeCategories' values as a tuple of sets of
unassigned, bases, ligatures, marks, components."""
font = self.context.font
unassigned, bases, ligatures, marks, components = (
set(),
set(),
set(),
set(),
set(),
)
openTypeCategories = font.lib.get(OPENTYPE_CATEGORIES_KEY, {})
# Handle case where we are a variable feature writer
if not openTypeCategories and isinstance(font, DesignSpaceDocument):
font = font.sources[0].font
openTypeCategories = font.lib.get(OPENTYPE_CATEGORIES_KEY, {})

for glyphName, category in openTypeCategories.items():
if category == "unassigned":
unassigned.add(glyphName)
elif category == "base":
bases.add(glyphName)
elif category == "ligature":
ligatures.add(glyphName)
elif category == "mark":
marks.add(glyphName)
elif category == "component":
components.add(glyphName)
else:
self.log.warning(
f"The '{OPENTYPE_CATEGORIES_KEY}' value of {glyphName} in "
f"{font.info.familyName} {font.info.styleName} is '{category}' "
"when it should be 'unassigned', 'base', 'ligature', 'mark' "
"or 'component'."
)
return namedtuple(
"OpenTypeCategories", "unassigned base ligature mark component"
)(
frozenset(unassigned),
frozenset(bases),
frozenset(ligatures),
frozenset(marks),
frozenset(components),
)
return OpenTypeCategories.load(self.context.font)

def getGDEFGlyphClasses(self):
"""Return a tuple of GDEF GlyphClassDef base, ligature, mark, component
Expand Down
55 changes: 53 additions & 2 deletions Lib/ufo2ft/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import re
from copy import deepcopy
from inspect import currentframe, getfullargspec
from typing import Any, Mapping, Set
from typing import Any, Mapping, NamedTuple, Set

from fontTools import subset, ttLib, unicodedata
from fontTools.designspaceLib import DesignSpaceDocument
Expand All @@ -15,7 +15,7 @@
from fontTools.pens.reverseContourPen import ReverseContourPen
from fontTools.pens.transformPen import TransformPen

from ufo2ft.constants import UNICODE_SCRIPT_ALIASES
from ufo2ft.constants import OPENTYPE_CATEGORIES_KEY, UNICODE_SCRIPT_ALIASES
from ufo2ft.errors import InvalidDesignSpaceData, InvalidFontData
from ufo2ft.fontInfoData import getAttrWithFallback

Expand Down Expand Up @@ -713,3 +713,54 @@ def collapse_varscalar(varscalar, threshold=0):
if not any(abs(v - values[0]) > threshold for v in values[1:]):
return list(varscalar.values.values())[0]
return varscalar


class OpenTypeCategories(NamedTuple):
unassigned: frozenset[str]
base: frozenset[str]
ligature: frozenset[str]
mark: frozenset[str]
component: frozenset[str]

@classmethod
def load(cls, font):
"""Return 'public.openTypeCategories' values as a tuple of sets of
unassigned, bases, ligatures, marks, components."""
unassigned, bases, ligatures, marks, components = (
set(),
set(),
set(),
set(),
set(),
)
openTypeCategories = font.lib.get(OPENTYPE_CATEGORIES_KEY, {})
# Handle case where we are a variable feature writer
if not openTypeCategories and isinstance(font, DesignSpaceDocument):
font = font.sources[0].font
openTypeCategories = font.lib.get(OPENTYPE_CATEGORIES_KEY, {})

for glyphName, category in openTypeCategories.items():
if category == "unassigned":
unassigned.add(glyphName)
elif category == "base":
bases.add(glyphName)
elif category == "ligature":
ligatures.add(glyphName)
elif category == "mark":
marks.add(glyphName)
elif category == "component":
components.add(glyphName)
else:
logging.getLogger("ufo2ft").warning(
f"The '{OPENTYPE_CATEGORIES_KEY}' value of {glyphName} in "
f"{font.info.familyName} {font.info.styleName} is '{category}' "
"when it should be 'unassigned', 'base', 'ligature', 'mark' "
"or 'component'."
)
return cls(
frozenset(unassigned),
frozenset(bases),
frozenset(ligatures),
frozenset(marks),
frozenset(components),
)

0 comments on commit 5cc53e2

Please sign in to comment.