def test_write_anchor(self): anchor = classes.GSAnchor("top", Point(23, 45.5)) self.assertWrites( anchor, dedent( """\ { name = top; position = "{23, 45.5}"; } """ ), ) # Write a position of 0, 0 anchor = classes.GSAnchor("top", Point(0, 0)) self.assertWrites( anchor, dedent( """\ { name = top; position = "{0, 0}"; } """ ), )
def test_write_background_image(self): image = classes.GSBackgroundImage("/tmp/img.jpg") # http://docu.glyphsapp.com/#gsbackgroundimage # path: already set # image: read-only, objective-c image.crop = Rect(Point(0, 10), Point(500, 510)) image.locked = True image.alpha = 70 image.position = Point(40, 90) image.scale = (1.1, 1.2) image.rotation = 0.3 # transform: Already set with scale/rotation self.assertWrites( image, dedent( """\ { alpha = 70; crop = "{{0, 10}, {500, 510}}"; imagePath = "/tmp/img.jpg"; locked = 1; transform = "{1.09998, 0.00576, -0.00628, 1.19998, 40, 90}"; } """ ), )
def test_write_component(self): component = classes.GSComponent("dieresis") # http://docu.glyphsapp.com/#gscomponent # position component.position = Point(45.5, 250) # scale component.scale = 2.0 # rotation component.rotation = 90 # componentName: already set at init # component: read-only # layer: read-only # transform: already set using scale & position # bounds: read-only, objective-c # automaticAlignment component.automaticAlignment = True # anchor component.anchor = "top" # selected: not written # smartComponentValues component.smartComponentValues = { "crotchDepth": -77, } # bezierPath: read-only, objective-c self.assertWrites(component, dedent("""\ { anchor = top; name = dieresis; piece = { crotchDepth = -77; }; transform = "{0, 2, -2, 0, 45.5, 250}"; } """))
def to_glyphs_glyph_anchors(self, ufo_glyph, layer): """Add UFO glif anchors to a GSLayer.""" for ufo_anchor in ufo_glyph.anchors: anchor = self.glyphs_module.GSAnchor() anchor.name = ufo_anchor.name anchor.position = Point(ufo_anchor.x, ufo_anchor.y) layer.anchors.append(anchor)
def test_write_hint(self): hint = classes.GSHint() # http://docu.glyphsapp.com/#gshint layer = classes.GSLayer() path1 = classes.GSPath() layer.paths.append(path1) node1 = classes.GSNode(Point(100, 100)) path1.nodes.append(node1) hint.originNode = node1 node2 = classes.GSNode(Point(200, 200)) path1.nodes.append(node2) hint.targetNode = node2 node3 = classes.GSNode(Point(300, 300)) path1.nodes.append(node3) hint.otherNode1 = node3 path2 = classes.GSPath() layer.paths.append(path2) node4 = classes.GSNode(Point(400, 400)) path2.nodes.append(node4) hint.otherNode2 = node4 hint.type = classes.CORNER hint.options = classes.TTROUND | classes.TRIPLE hint.horizontal = True # selected: not written hint.name = "My favourite hint" self.assertWrites( hint, dedent( """\ { horizontal = 1; origin = "{0, 0}"; target = "{0, 1}"; other1 = "{0, 2}"; other2 = "{1, 0}"; type = 16; name = "My favourite hint"; options = 128; } """ ), )
def test_write_node(self): node = classes.GSNode(Point(10, 30), classes.GSNode.CURVE) # http://docu.glyphsapp.com/#gsnode # position: already set # #type: already set # smooth node.smooth = True # connection: deprecated # selected: not written # index, nextNode, prevNode: computed # name node.name = "top-left corner" # userData node.userData["rememberToDownloadARealRemindersApp"] = True self.assertWritesValue( node, '"10 30 CURVE SMOOTH {name = \\"top-left corner\\";\\n\ rememberToDownloadARealRemindersApp = 1;}"', ) # Write floating point coordinates node = classes.GSNode(Point(499.99, 512.01), classes.GSNode.OFFCURVE) self.assertWritesValue(node, '"499.99 512.01 OFFCURVE"') # Write userData with special characters test_user_data = { "\nkey\"';\n\n\n": "\"'value\nseveral lines\n;\n", ";": ";\n", "escapeception": "\\\"\\'\\n\\\\n", } node = classes.GSNode(Point(130, 431), classes.GSNode.LINE) for key, value in test_user_data.items(): node.userData[key] = value # This is the output of Glyphs 1089 expected_output = ( '"130 431 LINE {\\"\\012key\\\\"\';\\012\\012\\012\\" ' '= \\"\\\\"\'value\\012several lines\\012;\\012\\"' ';\\n\\";\\" = \\";\\012\\";\\n' 'escapeception = \\"\\\\\\\\"\\\\\'\\\\\\n\\\\\\\\\\n\\";}"' ) self.assertWritesValue(node, expected_output) # Check that we can read the userData back node = Parser(classes.GSNode).parse(expected_output) self.assertEqual(test_user_data, dict(node.userData))
def to_glyphs_hints(self, ufo_glyph, layer): if LIB_KEY not in ufo_glyph.lib: return for hint in ufo_glyph.lib[LIB_KEY]: hi = self.glyphs_module.GSHint() for attr in ["horizontal", "options", "stem", "type"]: setattr(hi, attr, hint[attr]) for attr in ["origin", "other1", "other2", "place", "scale", "target"]: # FIXME: (jany) what about target = up/down? if attr in hint: value = Point(*hint[attr]) setattr(hi, attr, value) layer.hints.append(hi)
def to_glyphs_hints(self, ufo_glyph, layer): if LIB_KEY not in ufo_glyph.lib: return for hint in ufo_glyph.lib[LIB_KEY]: hi = self.glyphs_module.GSHint() for attr in ['horizontal', 'options', 'stem', 'type']: setattr(hi, attr, hint[attr]) for attr in ['origin', 'other1', 'other2', 'place', 'scale', 'target']: # FIXME: (jany) what about target = up/down? if attr in hint: value = Point(*hint[attr]) setattr(hi, attr, value) layer.hints.append(hi)
def test_write_guideline(self): line = classes.GSGuideLine() # http://docu.glyphsapp.com/#GSGuideLine line.position = Point(56, 45) line.angle = 11.0 line.name = "italic angle" # selected: not written self.assertWrites(line, dedent("""\ { angle = 11; name = "italic angle"; position = "{56, 45}"; } """))
def to_glyphs_annotations(self, ufo_glyph, layer): if LIB_KEY not in ufo_glyph.lib: return for annot in ufo_glyph.lib[LIB_KEY]: annotation = self.glyphs_module.GSAnnotation() for attr in ['angle', 'position', 'text', 'type', 'width']: if attr in annot and annot[attr]: if attr == 'position': # annot['position'] can be either "{1, 2}" or (1, 2) position = Point(annot['position']) annotation.position = position else: setattr(annotation, attr, annot[attr]) layer.annotations.append(annotation)
def to_glyphs_background_image(self, ufo_glyph, layer): """Copy the background image from the UFO Glyph to the GSLayer.""" ufo_image = ufo_glyph.image if ufo_image.fileName is None: return image = self.glyphs_module.GSBackgroundImage() image.path = ufo_image.fileName image.transform = Transform(*ufo_image.transformation) if CROP_KEY in ufo_glyph.lib: x, y, w, h = ufo_glyph.lib[CROP_KEY] image.crop = Rect(Point(x, y), Size(w, h)) if LOCKED_KEY in ufo_glyph.lib: image.locked = ufo_glyph.lib[LOCKED_KEY] if ALPHA_KEY in ufo_glyph.lib: image.alpha = ufo_glyph.lib[ALPHA_KEY] layer.backgroundImage = image
def _run_guideline_test(self, data_in, expected): font = generate_minimal_font() glyph = GSGlyph(name='a') font.glyphs.append(glyph) layer = GSLayer() layer.layerId = font.masters[0].id layer.width = 0 for guide_data in data_in: pt = Point(value=guide_data['position'][0], value2=guide_data['position'][1]) guide = GSGuideLine() guide.position = pt guide.angle = guide_data['angle'] layer.guides.append(guide) glyph.layers.append(layer) ufo = to_ufos(font)[0] self.assertEqual(ufo['a'].guidelines, expected)
def test_write_annotation(self): annotation = classes.GSAnnotation() # http://docu.glyphsapp.com/#gsannotation annotation.position = Point(12, 34) annotation.type = classes.TEXT annotation.text = "Look here" annotation.angle = 123.5 annotation.width = 135 self.assertWrites(annotation, dedent("""\ { angle = 123.5; position = "{12, 34}"; text = "Look here"; type = 1; width = 135; } """))
def to_glyphs_hints(self, ufo_glyph, layer): if LIB_KEY not in ufo_glyph.lib: return for hint in ufo_glyph.lib[LIB_KEY]: hi = self.glyphs_module.GSHint() for attr in ["horizontal", "options", "stem", "type"]: setattr(hi, attr, hint[attr]) for attr in ["origin", "other1", "other2", "place", "scale", "target"]: if attr in hint: # https://github.com/googlefonts/glyphsLib/pull/613 # handle target = ['u', 'p'] or ['d', 'o', 'w', 'n'] if attr == "target" and hint[attr] in (list("down"), list("up")): value = "".join(hint[attr]) # handle target = "up" or "down" elif attr == "target" and hint[attr] in ("down", "up"): value = hint[attr] else: value = Point(*hint[attr]) setattr(hi, attr, value) layer.hints.append(hi)
def to_glyphs_guidelines(self, ufo_obj, glyphs_obj): """Set guidelines.""" if not ufo_obj.guidelines: return for guideline in ufo_obj.guidelines: new_guideline = self.glyphs_module.GSGuideLine() name = guideline.name # Locked if name is not None and name.endswith(LOCKED_NAME_SUFFIX): name = name[:-len(LOCKED_NAME_SUFFIX)] new_guideline.locked = True if guideline.color: name = (name or '') + COLOR_NAME_SUFFIX % str(guideline.color) if guideline.identifier: name = (name or '') + IDENTIFIER_NAME_SUFFIX % guideline.identifier new_guideline.name = name new_guideline.position = Point(guideline.x or 0, guideline.y or 0) if guideline.angle is not None: new_guideline.angle = (360 - guideline.angle) % 360 elif _is_vertical(guideline.x, guideline.y, None): new_guideline.angle = 90 glyphs_obj.guides.append(new_guideline)