Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split the UFO builder into 1 file per "feature" #235

Merged
merged 6 commits into from
Oct 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Lib/glyphsLib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@


def load_to_ufos(file_or_path, include_instances=False, family_name=None,
propagate_anchors=True, debug=False):
propagate_anchors=True):
"""Load an unpacked .glyphs object to UFO objects."""

if hasattr(file_or_path, 'read'):
Expand All @@ -55,8 +55,7 @@ def load_to_ufos(file_or_path, include_instances=False, family_name=None,
logger.info('Loading to UFOs')
return to_ufos(font, include_instances=include_instances,
family_name=family_name,
propagate_anchors=propagate_anchors,
debug=debug)
propagate_anchors=propagate_anchors)


def build_masters(filename, master_dir, designspace_instance_dir=None,
Expand Down
46 changes: 44 additions & 2 deletions Lib/glyphsLib/builder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,48 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .glyphs import to_glyphs
import logging

from .ufo import to_ufos, logger
from glyphsLib import classes
import defcon

from .builders import UFOBuilder, GlyphsBuilder

logger = logging.getLogger(__name__)


def to_ufos(font, include_instances=False, family_name=None,
propagate_anchors=True, ufo_module=defcon):
"""Take .glyphs file data and load it into UFOs.

Takes in data as Glyphs.app-compatible classes, as documented at
https://docu.glyphsapp.com/

If include_instances is True, also returns the parsed instance data.

If family_name is provided, the master UFOs will be given this name and
only instances with this name will be returned.
"""
builder = UFOBuilder(
font,
ufo_module=ufo_module,
family_name=family_name,
propagate_anchors=propagate_anchors)

result = list(builder.masters)

if include_instances:
return result, builder.instance_data
return result


def to_glyphs(ufos, designspace=None, glyphs_module=classes):
"""
Take a list of UFOs and combine them into a single .glyphs file.

This should be the inverse function of `to_ufos`,
so we should have to_glyphs(to_ufos(font)) == font
"""
builder = GlyphsBuilder(
ufos, designspace=designspace, glyphs_module=glyphs_module)
return builder.font
29 changes: 19 additions & 10 deletions Lib/glyphsLib/anchors.py → Lib/glyphsLib/builder/anchors.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@

from fontTools.misc.transform import Transform

__all__ = ['propagate_font_anchors']
__all__ = ['to_ufo_propagate_font_anchors']


def propagate_font_anchors(ufo):
def to_ufo_propagate_font_anchors(self, ufo):
"""Copy anchors from parent glyphs' components to the parent."""

processed = set()
for glyph in ufo:
propagate_glyph_anchors(ufo, glyph, processed)
_propagate_glyph_anchors(ufo, glyph, processed)


def propagate_glyph_anchors(ufo, parent, processed):
def _propagate_glyph_anchors(ufo, parent, processed):
"""Propagate anchors for a single parent glyph."""

if parent.name in processed:
Expand All @@ -42,7 +42,7 @@ def propagate_glyph_anchors(ufo, parent, processed):
to_add = {}
for component in parent.components:
glyph = ufo[component.baseGlyph]
propagate_glyph_anchors(ufo, glyph, processed)
_propagate_glyph_anchors(ufo, glyph, processed)
if any(a.name.startswith('_') for a in glyph.anchors):
mark_components.append(component)
else:
Expand All @@ -53,18 +53,18 @@ def propagate_glyph_anchors(ufo, parent, processed):
# don't add if parent already contains this anchor OR any associated
# ligature anchors (e.g. "top_1, top_2" for "top")
if not any(a.name.startswith(anchor_name) for a in parent.anchors):
get_anchor_data(to_add, ufo, base_components, anchor_name)
_get_anchor_data(to_add, ufo, base_components, anchor_name)

for component in mark_components:
adjust_anchors(to_add, ufo, component)
_adjust_anchors(to_add, ufo, component)

# we sort propagated anchors to append in a deterministic order
for name, (x, y) in sorted(to_add.items()):
anchor_dict = {'name': name, 'x': x, 'y': y}
parent.appendAnchor(glyph.anchorClass(anchorDict=anchor_dict))


def get_anchor_data(anchor_data, ufo, components, anchor_name):
def _get_anchor_data(anchor_data, ufo, components, anchor_name):
"""Get data for an anchor from a list of components."""

anchors = []
Expand All @@ -84,7 +84,7 @@ def get_anchor_data(anchor_data, ufo, components, anchor_name):
anchor_data[anchor.name] = t.transformPoint((anchor.x, anchor.y))


def adjust_anchors(anchor_data, ufo, component):
def _adjust_anchors(anchor_data, ufo, component):
"""Adjust anchors to which a mark component may have been attached."""

glyph = ufo[component.baseGlyph]
Expand All @@ -93,5 +93,14 @@ def adjust_anchors(anchor_data, ufo, component):
# only adjust if this anchor has data and the component also contains
# the associated mark anchor (e.g. "_top" for "top")
if (anchor.name in anchor_data and
any(a.name == '_' + anchor.name for a in glyph.anchors)):
any(a.name == '_' + anchor.name for a in glyph.anchors)):
anchor_data[anchor.name] = t.transformPoint((anchor.x, anchor.y))


def to_ufo_glyph_anchors(self, glyph, anchors):
"""Add .glyphs anchors to a glyph."""

for anchor in anchors:
x, y = anchor.position
anchor_dict = {'name': anchor.name, 'x': x, 'y': y}
glyph.appendAnchor(anchor_dict)
36 changes: 36 additions & 0 deletions Lib/glyphsLib/builder/blue_values.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import (print_function, division, absolute_import,
unicode_literals)


def to_ufo_blue_values(self, ufo, master):
"""Set postscript blue values from Glyphs alignment zones."""

alignment_zones = master.alignmentZones
blue_values = []
other_blues = []
for zone in sorted(alignment_zones):
pos = zone.position
size = zone.size
val_list = blue_values if pos == 0 or size >= 0 else other_blues
val_list.extend(sorted((pos, pos + size)))

ufo.info.postscriptBlueValues = blue_values
ufo.info.postscriptOtherBlues = other_blues


def to_glyphs_blue_values(self, ufo, master):
pass
Loading