Skip to content

Commit

Permalink
Merge pull request #1011 from googlefonts/new-propagate-anchors
Browse files Browse the repository at this point in the history
Port fontc' propagate_anchors.rs to .py; apply it as preflight transformation
  • Loading branch information
anthrotype authored Aug 8, 2024
2 parents aa7a03a + 56677c9 commit 8698f2c
Show file tree
Hide file tree
Showing 12 changed files with 7,531 additions and 22 deletions.
58 changes: 49 additions & 9 deletions Lib/glyphsLib/builder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from glyphsLib import classes

from .builders import UFOBuilder, GlyphsBuilder
from .transformations import TRANSFORMATIONS
from .transformations import TRANSFORMATIONS, TRANSFORMATION_CUSTOM_PARAMS

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -64,11 +64,13 @@ def to_ufos(
"""
if preserve_original:
font = copy.deepcopy(font)
font = preflight_glyphs(
font, glyph_data=glyph_data, do_propagate_all_anchors=propagate_anchors
)
builder = UFOBuilder(
preflight_glyphs(font),
font,
ufo_module=ufo_module,
family_name=family_name,
propagate_anchors=propagate_anchors,
minimize_glyphs_diffs=minimize_glyphs_diffs,
generate_GDEF=generate_GDEF,
store_editor_state=store_editor_state,
Expand Down Expand Up @@ -129,13 +131,14 @@ def to_designspace(
"""
if preserve_original:
font = copy.deepcopy(font)

font = preflight_glyphs(
font, glyph_data=glyph_data, do_propagate_all_anchors=propagate_anchors
)
builder = UFOBuilder(
preflight_glyphs(font),
font,
ufo_module=ufo_module,
family_name=family_name,
instance_dir=instance_dir,
propagate_anchors=propagate_anchors,
use_designspace=True,
minimize_glyphs_diffs=minimize_glyphs_diffs,
generate_GDEF=generate_GDEF,
Expand All @@ -148,12 +151,49 @@ def to_designspace(
return builder.designspace


def preflight_glyphs(font):
def preflight_glyphs(font, *, glyph_data=None, **flags):
"""Run a set of transformations over a GSFont object to make
it easier to convert to UFO; resolve all the "smart stuff"."""
it easier to convert to UFO; resolve all the "smart stuff".
Currently, the transformations are:
- `propagate_all_anchors`: copy anchors from components to their parent
More transformations may be added in the future.
Some transformations may have custom parameters that can be set in the
font. For example, the `propagate_all_anchors` transformation can be
disabled by setting the custom parameter "Propagate Anchors" to False
(see `TRANSFORMATION_CUSTOM_PARAMS`).
Args:
font: a GSFont object
glyph_data: an optional GlyphData object associating various properties to
glyph names (e.g. category) that overrides the default one
**flags: a set of boolean flags to enable/disable specific transformations,
named `do_<transformation_name>`, e.g. `do_propagate_all_anchors=False`
will disable the propagation of anchors.
Returns:
the modified GSFont object
"""

for transform in TRANSFORMATIONS:
transform(font)
do_transform = flags.pop("do_" + transform.__name__, None)
if do_transform is True:
pass
elif do_transform is False:
continue
elif do_transform is None:
if transform in TRANSFORMATION_CUSTOM_PARAMS:
param = TRANSFORMATION_CUSTOM_PARAMS[transform]
if not font.customParameters.get(param.name, param.default):
continue
else:
raise ValueError(f"Invalid value for do_{transform.__name__}")
logger.info(f"Running '{transform.__name__}' transformation")
transform(font, glyph_data=glyph_data)
if flags:
logger.warning(f"preflight_glyphs has unused `flags` arguments: {flags}")
return font


Expand Down
8 changes: 8 additions & 0 deletions Lib/glyphsLib/builder/anchor_propagation.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""This module is DEPRECATED and will be removed in a future release.
For anchor propagation on GSFont objects, you can use the
`glyphsLib.builder.transformations.propagate_anchors` module.
For anchor propagation on UFO font objects, you can try the
`ufo2ft.filters.propagateAnchors` filter.
"""

from fontTools.misc.transform import Transform
import fontTools.pens.boundsPen

Expand Down
26 changes: 17 additions & 9 deletions Lib/glyphsLib/builder/builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
FONT_CUSTOM_PARAM_PREFIX,
)
from .axes import WEIGHT_AXIS_DEF, WIDTH_AXIS_DEF, find_base_style, class_to_value
from glyphsLib.util import LoggerMixin
from glyphsLib.util import LoggerMixin, _DeprecatedArgument


class UFOBuilder(LoggerMixin):
Expand All @@ -41,7 +41,7 @@ def __init__(
designspace_module=designspaceLib,
family_name=None,
instance_dir=None,
propagate_anchors=None,
propagate_anchors=_DeprecatedArgument, # DEPRECATED
use_designspace=False,
minimize_glyphs_diffs=False,
generate_GDEF=True,
Expand All @@ -66,9 +66,8 @@ def __init__(
only instances with this name will be returned.
instance_dir -- if provided, instance UFOs will be located in this
directory, according to their Designspace filenames.
propagate_anchors -- set to True or False to explicitly control anchor
propagation, the default is to check for
"Propagate Anchors" custom parameter.
propagate_anchors -- DEPRECATED. Use preflight_glyphs to propagate anchors on
the GSFont before building UFOs.
use_designspace -- set to True to make optimal use of the designspace:
data that is common to all ufos will go there.
minimize_glyphs_diffs -- set to True to store extra info in UFOs
Expand Down Expand Up @@ -106,9 +105,18 @@ def __init__(
self.expand_includes = expand_includes
self.minimal = minimal

if propagate_anchors is None:
propagate_anchors = font.customParameters["Propagate Anchors"]
propagate_anchors = bool(propagate_anchors is None or propagate_anchors)
if propagate_anchors is not _DeprecatedArgument:
from warnings import warn

warn(
"The 'propagate_anchors' argument is deprecated and will be removed "
"in a future version. "
"Use glyphsLib.builder.preflight_glyphs to propagate anchors on the "
"GSFont before building UFOs.",
DeprecationWarning,
)
else:
propagate_anchors = False
self.propagate_anchors = propagate_anchors

# The set of (SourceDescriptor + UFO)s that will be built,
Expand Down Expand Up @@ -215,7 +223,7 @@ def masters(self):
for master_id, source in self._sources.items():
ufo = source.font
master = self.font.masters[master_id]
if self.propagate_anchors:
if self.propagate_anchors: # deprecated, will be removed one day
self.to_ufo_propagate_font_anchors(ufo) # .anchor_propagation
if not self.minimal:
for layer in list(ufo.layers):
Expand Down
21 changes: 20 additions & 1 deletion Lib/glyphsLib/builder/transformations/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
TRANSFORMATIONS = []
from types import MappingProxyType
from typing import NamedTuple

from .propagate_anchors import propagate_all_anchors

TRANSFORMATIONS = [
propagate_all_anchors,
]


class _CustomParameter(NamedTuple):
name: str
default: bool


TRANSFORMATION_CUSTOM_PARAMS = MappingProxyType(
{
propagate_all_anchors: _CustomParameter("Propagate Anchors", True),
}
)
Loading

0 comments on commit 8698f2c

Please sign in to comment.