Skip to content

Commit

Permalink
WIP Glyph, Layer, Node user data
Browse files Browse the repository at this point in the history
  • Loading branch information
belluzj committed Oct 31, 2017
1 parent d65f45c commit 973db18
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 39 deletions.
9 changes: 7 additions & 2 deletions Lib/glyphsLib/builder/builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ def instance_data(self):
to_ufo_kerning_groups)
from .names import to_ufo_names
from .paths import to_ufo_draw_paths
from .user_data import to_ufo_family_user_data, to_ufo_master_user_data
from .user_data import (to_ufo_family_user_data, to_ufo_master_user_data,
to_ufo_glyph_user_data, to_ufo_layer_user_data,
to_ufo_node_user_data)


def filter_instances_by_family(instances, family_name=None):
Expand Down Expand Up @@ -320,4 +322,7 @@ def font(self):
from .names import to_glyphs_family_names, to_glyphs_master_names
from .paths import to_glyphs_draw_paths
from .user_data import (to_glyphs_family_user_data,
to_glyphs_master_user_data)
to_glyphs_master_user_data,
to_glyphs_glyph_user_data,
to_glyphs_layer_user_data,
to_glyphs_node_user_data)
3 changes: 2 additions & 1 deletion Lib/glyphsLib/builder/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
from .constants import GLYPHS_PREFIX


def to_ufo_draw_components(self, pen, components):
def to_ufo_draw_components(self, ufo_glyph, components):
"""Draw .glyphs components onto a pen, adding them to the parent glyph."""
pen = ufo_glyph.getPointPen()

for component in components:
pen.addComponent(component.name,
Expand Down
15 changes: 9 additions & 6 deletions Lib/glyphsLib/builder/glyph.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ def to_ufo_glyph(self, ufo_glyph, layer, glyph):
self.to_ufo_annotations(ufo_glyph, layer)
self.to_ufo_hints(ufo_glyph, layer)
self.to_ufo_component_data(ufo_glyph, layer)
self.to_ufo_glyph_user_data(ufo_glyph, glyph)
self.to_ufo_layer_user_data(ufo_glyph, layer)

pen = ufo_glyph.getPointPen()
self.to_ufo_draw_paths(pen, layer.paths)
self.to_ufo_draw_components(pen, layer.components)
self.to_ufo_draw_paths(ufo_glyph, layer.paths)
self.to_ufo_draw_components(ufo_glyph, layer.components)
self.to_ufo_glyph_anchors(ufo_glyph, layer.anchors)


Expand Down Expand Up @@ -197,6 +198,8 @@ def to_glyphs_glyph(self, ufo_glyph, ufo_layer, master):
self.to_glyphs_annotations(ufo_glyph, layer)
self.to_glyphs_hints(ufo_glyph, layer)
self.to_glyphs_component_data(ufo_glyph, layer)
self.to_glyphs_glyph_user_data(ufo_glyph, glyph)
self.to_glyphs_layer_user_data(ufo_glyph, layer)

self.to_glyphs_draw_paths(ufo_glyph, layer)
self.to_glyphs_draw_components(ufo_glyph, layer)
Expand All @@ -220,9 +223,9 @@ def to_ufo_glyph_background(self, glyph, background):
layer = font.layers[layer_name]
new_glyph = layer.newGlyph(glyph.name)
new_glyph.width = glyph.width
pen = new_glyph.getPointPen()
self.to_ufo_draw_paths(pen, background.paths)
self.to_ufo_draw_components(pen, background.components)

self.to_ufo_draw_paths(new_glyph, background.paths)
self.to_ufo_draw_components(new_glyph, background.components)
self.to_ufo_glyph_anchors(new_glyph, background.anchors)
self.to_ufo_guidelines(new_glyph, background)

Expand Down
11 changes: 8 additions & 3 deletions Lib/glyphsLib/builder/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
from glyphsLib import classes


def to_ufo_draw_paths(self, pen, paths):
def to_ufo_draw_paths(self, ufo_glyph, paths):
"""Draw .glyphs paths onto a pen."""
pen = ufo_glyph.getPointPen()

for path in paths:
pen.beginPath()
nodes = list(path.nodes) # the list is changed below, otherwise you can't draw more than once per session.
for node in nodes:
self.to_ufo_node_user_data(ufo_glyph, node)

pen.beginPath()
if not nodes:
pen.endPath()
continue
Expand All @@ -52,13 +55,15 @@ def to_glyphs_draw_paths(self, ufo_glyph, layer):
node.type = _to_glyphs_node_type(point.segmentType)
node.smooth = point.smooth
node.name = point.name
# TODO: (jany) Restore node userData
path.nodes.append(node)
if not contour.open:
path.closed = True
path.nodes.append(path.nodes.pop(0))
layer.paths.append(path)

for node in path.nodes:
self.to_glyphs_node_user_data(ufo_glyph, node)


def _to_ufo_node_type(node_type):
if node_type not in ['line', 'curve', 'qcurve']:
Expand Down
42 changes: 42 additions & 0 deletions Lib/glyphsLib/builder/user_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
from .constants import GLYPHS_PREFIX

MASTER_USER_DATA_KEY = GLYPHS_PREFIX + 'fontMaster.userData'
LAYER_USER_DATA_KEY = GLYPHS_PREFIX + 'layer.userData'
GLYPH_USER_DATA_KEY = GLYPHS_PREFIX + 'glyph.userData'
NODE_USER_DATA_KEY = GLYPHS_PREFIX + 'node.userData'


def to_ufo_family_user_data(self, ufo):
Expand All @@ -41,6 +44,27 @@ def to_ufo_master_user_data(self, ufo, master):
ufo.lib[MASTER_USER_DATA_KEY] = data


def to_ufo_glyph_user_data(self, ufo_glyph, glyph):
user_data = glyph.userData
if user_data:
ufo_glyph.lib[GLYPH_USER_DATA_KEY] = dict(user_data)


def to_ufo_layer_user_data(self, ufo_glyph, layer):
user_data = layer.userData
if user_data:
key = LAYER_USER_DATA_KEY + '.' + layer.layerId
ufo_glyph.lib[key] = dict(user_data)


def to_ufo_node_user_data(self, ufo_glyph, node):
user_data = node.userData
if user_data:
path_index, node_index = node._indices()
key = '{}.{}.{}'.format(NODE_USER_DATA_KEY, path_index, node_index)
ufo_glyph.lib[key] = dict(user_data)


def to_glyphs_family_user_data(self, ufo):
"""Set the GSFont userData from the UFO family-wide user data."""
target_user_data = self.font.userData
Expand All @@ -58,6 +82,24 @@ def to_glyphs_master_user_data(self, ufo, master):
master.userData = user_data


def to_glyphs_glyph_user_data(self, ufo_glyph, glyph):
if GLYPH_USER_DATA_KEY in ufo_glyph.lib:
glyph.userData = ufo_glyph.lib[GLYPH_USER_DATA_KEY]


def to_glyphs_layer_user_data(self, ufo_glyph, layer):
key = LAYER_USER_DATA_KEY + '.' + layer.layerId
if key in ufo_glyph.lib:
layer.userData = ufo_glyph.lib[key]


def to_glyphs_node_user_data(self, ufo_glyph, node):
path_index, node_index = node._indices()
key = '{}.{}.{}'.format(NODE_USER_DATA_KEY, path_index, node_index)
if key in ufo_glyph.lib:
node.userData = ufo_glyph.lib[key]


def _user_data_was_originally_there_family_wide(key):
# FIXME: (jany) Identify better which keys must be brought back?
return not key.startswith(GLYPHS_PREFIX)
56 changes: 29 additions & 27 deletions Lib/glyphsLib/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1434,6 +1434,17 @@ def connection(self):
def selected(self):
raise OnlyInGlyphsAppError

def _indices(self):
"""Find the path_index and node_index that identify the given node."""
path = self.parent
layer = path.parent
for path_index in range(len(layer.paths)):
if path == layer.paths[path_index]:
for node_index in range(len(path.nodes)):
if self == path.nodes[node_index]:
return point(path_index, node_index)
return None


class GSPath(GSBase):
_classesForName = {
Expand Down Expand Up @@ -1946,31 +1957,12 @@ def __repr__(self):
def parent(self):
return self._parent

def _find_node_by_indices(self, point):
""""Find the GSNode that is refered to by the given indices."""
path_index, node_index = point
layer = self.parent
path = layer.paths[int(path_index)]
node = path.nodes[int(node_index)]
return node

def _find_indices_for_node(self, node):
"""Find the path_index and node_index that identify the given node."""
path = node.parent
layer = path.parent
for path_index in range(len(layer.paths)):
if path == layer.paths[path_index]:
for node_index in range(len(path.nodes)):
if node == path.nodes[node_index]:
return point(path_index, node_index)
return None

@property
def originNode(self):
if self._originNode is not None:
return self._originNode
if self._origin is not None:
return self._find_node_by_indices(self._origin)
return self.parent._find_node_by_indices(self._origin)

@originNode.setter
def originNode(self, node):
Expand All @@ -1982,7 +1974,7 @@ def origin(self):
if self._origin is not None:
return self._origin
if self._originNode is not None:
return self._find_indices_for_node(self._originNode)
return self._originNode._indices()

@origin.setter
def origin(self, origin):
Expand All @@ -1994,7 +1986,7 @@ def targetNode(self):
if self._targetNode is not None:
return self._targetNode
if self._target is not None:
return self._find_node_by_indices(self._target)
return self.parent._find_node_by_indices(self._target)

@targetNode.setter
def targetNode(self, node):
Expand All @@ -2006,7 +1998,7 @@ def target(self):
if self._target is not None:
return self._target
if self._targetNode is not None:
return self._find_indices_for_node(self._targetNode)
return self._targetNode._indices()

@target.setter
def target(self, target):
Expand All @@ -2018,7 +2010,7 @@ def otherNode1(self):
if self._otherNode1 is not None:
return self._otherNode1
if self._other1 is not None:
return self._find_node_by_indices(self._other1)
return self.parent._find_node_by_indices(self._other1)

@otherNode1.setter
def otherNode1(self, node):
Expand All @@ -2030,7 +2022,7 @@ def other1(self):
if self._other1 is not None:
return self._other1
if self._otherNode1 is not None:
return self._find_indices_for_node(self._otherNode1)
return self._otherNode1._indices()

@other1.setter
def other1(self, other1):
Expand All @@ -2042,7 +2034,7 @@ def otherNode2(self):
if self._otherNode2 is not None:
return self._otherNode2
if self._other2 is not None:
return self._find_node_by_indices(self._other2)
return self.parent._find_node_by_indices(self._other2)

@otherNode2.setter
def otherNode2(self, node):
Expand All @@ -2054,7 +2046,7 @@ def other2(self):
if self._other2 is not None:
return self._other2
if self._otherNode2 is not None:
return self._find_indices_for_node(self._otherNode2)
return self._otherNode2._indices()

@other2.setter
def other2(self, other2):
Expand Down Expand Up @@ -2556,6 +2548,16 @@ def bounds(self):
if left is not None and bottom is not None and right is not None and top is not None:
return rect(point(left, bottom), point(right - left, top - bottom))

def _find_node_by_indices(self, point):
""""Find the GSNode that is refered to by the given indices.
See GSNode::_indices()
"""
path_index, node_index = point
path = self.paths[int(path_index)]
node = path.nodes[int(node_index)]
return node


class GSGlyph(GSBase):
_classesForName = {
Expand Down

0 comments on commit 973db18

Please sign in to comment.