Ejemplo n.º 1
0
    def test_family_name_custom(self):
        font = generate_minimal_font()
        instances_list = [{
            'name': 'Regular1'
        }, {
            'name':
            'Regular2',
            'customParameters': [
                {
                    'name': 'familyName',
                    'value': 'CustomFamily'
                },
            ]
        }]
        font.instances = [
            generate_instance_from_dict(i) for i in instances_list
        ]
        ufos, instance_data = to_ufos(font,
                                      include_instances=True,
                                      family_name='CustomFamily')
        instances = instance_data['data']

        # only instances with familyName='CustomFamily' are included
        self.assertEqual(len(instances), 1)
        self.assertEqual(instances[0].name, 'Regular2')
        self.assertEqual(len(instances[0].customParameters), 1)
        self.assertEqual(instances[0].customParameters[0].value,
                         'CustomFamily')

        # the masters' family is also modified to use custom 'family_name'
        for ufo in ufos:
            self.assertEqual(ufo.info.familyName, 'CustomFamily')
Ejemplo n.º 2
0
    def test_family_name_none(self):
        font = generate_minimal_font()
        instances_list = [{
            'name': 'Regular1'
        }, {
            'name':
            'Regular2',
            'customParameters': [
                {
                    'name': 'familyName',
                    'value': 'CustomFamily'
                },
            ]
        }]
        font.instances = [
            generate_instance_from_dict(i) for i in instances_list
        ]

        # 'family_name' defaults to None
        ufos, instance_data = to_ufos(font, include_instances=True)
        instances = instance_data['data']

        # all instances are included, both with/without 'familyName' parameter
        self.assertEqual(len(instances), 2)
        self.assertEqual(instances[0].name, 'Regular1')
        self.assertEqual(instances[1].name, 'Regular2')
        self.assertEqual(len(instances[0].customParameters), 0)
        self.assertEqual(len(instances[1].customParameters), 1)
        self.assertEqual(instances[1].customParameters[0].value,
                         'CustomFamily')

        # the masters' family name is unchanged
        for ufo in ufos:
            self.assertEqual(ufo.info.familyName, 'MyFont')
Ejemplo n.º 3
0
    def test_family_name_same_as_default(self):
        font = generate_minimal_font()
        instances_list = [{
            'name': 'Regular1'
        }, {
            'name':
            'Regular2',
            'customParameters': [
                {
                    'name': 'familyName',
                    'value': 'CustomFamily'
                },
            ]
        }]
        font.instances = [
            generate_instance_from_dict(i) for i in instances_list
        ]
        # 'MyFont' is the source family name, as returned from
        # 'generate_minimal_data'
        ufos, instance_data = to_ufos(font,
                                      include_instances=True,
                                      family_name='MyFont')
        instances = instance_data['data']

        # only instances which don't have 'familyName' custom parameter
        # are included in returned list
        self.assertEqual(len(instances), 1)
        self.assertEqual(instances[0].name, 'Regular1')
        self.assertEqual(len(instances[0].customParameters), 0)

        # the masters' family name is unchanged
        for ufo in ufos:
            self.assertEqual(ufo.info.familyName, 'MyFont')
    def test_master_with_light_weight_but_thin_name(self):
        font = generate_minimal_font()
        master = font.masters[0]
        name = 'Thin'  # In Glyphs.app, show "Thin" in the sidebar
        weight = 'Light'  # In Glyphs.app, have the light "n" icon
        width = None  # No data => should be equivalent to Regular
        custom_name = 'Thin'
        master.set_all_name_components(name, weight, width, custom_name)
        assert master.name == 'Thin'
        assert master.weight == 'Light'

        ufo, = to_ufos(font)
        font_rt = to_glyphs([ufo])
        master_rt = font_rt.masters[0]

        assert master_rt.name == 'Thin'
        assert master_rt.weight == 'Light'

        tmpdir = tempfile.mkdtemp()
        try:
            filename = os.path.join(tmpdir, 'test.glyphs')
            font_rt.save(filename)
            font_rt_written = GSFont(filename)

            master_rt_written = font_rt_written.masters[0]

            assert master_rt_written.name == 'Thin'
            assert master_rt_written.weight == 'Light'
        finally:
            shutil.rmtree(tmpdir)
Ejemplo n.º 5
0
    def test_glyph_lib_componentsAlignment_and_componentsLocked(self):
        font = generate_minimal_font()
        add_glyph(font, "a")
        add_glyph(font, "b")
        composite_glyph = add_glyph(font, "c")
        add_component(font, "c", "a", (1, 0, 0, 1, 0, 0))
        add_component(font, "c", "b", (1, 0, 0, 1, 0, 100))
        comp1 = composite_glyph.layers[0].components[0]
        comp2 = composite_glyph.layers[0].components[1]

        self.assertEqual(comp1.alignment, 0)
        self.assertEqual(comp1.locked, False)

        ufo = to_ufos(font)[0]

        # all components have deault values, no lib key is written
        self.assertNotIn(GLYPHS_PREFIX + "componentsAlignment", ufo["c"].lib)
        self.assertNotIn(GLYPHS_PREFIX + "componentsLocked", ufo["c"].lib)

        comp2.alignment = -1
        comp1.locked = True
        ufo = to_ufos(font)[0]

        # if any component has a non-default alignment/locked values, write
        # list of values for all of them
        self.assertIn(GLYPHS_PREFIX + "componentsAlignment", ufo["c"].lib)
        self.assertEqual(ufo["c"].lib[GLYPHS_PREFIX + "componentsAlignment"],
                         [0, -1])
        self.assertIn(GLYPHS_PREFIX + "componentsLocked", ufo["c"].lib)
        self.assertEqual(ufo["c"].lib[GLYPHS_PREFIX + "componentsLocked"],
                         [True, False])
Ejemplo n.º 6
0
 def test_glyph_color(self):
     font = generate_minimal_font()
     glyph = GSGlyph(name='a')
     glyph2 = GSGlyph(name='b')
     glyph3 = GSGlyph(name='c')
     glyph4 = GSGlyph(name='d')
     glyph.color = [244, 0, 138, 1]
     glyph2.color = 3
     glyph3.color = 88
     glyph4.color = [800, 0, 138, 1]
     font.glyphs.append(glyph)
     font.glyphs.append(glyph2)
     font.glyphs.append(glyph3)
     font.glyphs.append(glyph4)
     layer = GSLayer()
     layer2 = GSLayer()
     layer3 = GSLayer()
     layer4 = GSLayer()
     layer.layerId = font.masters[0].id
     layer2.layerId = font.masters[0].id
     layer3.layerId = font.masters[0].id
     layer4.layerId = font.masters[0].id
     glyph.layers.append(layer)
     glyph2.layers.append(layer2)
     glyph3.layers.append(layer3)
     glyph4.layers.append(layer4)
     ufo = to_ufos(font)[0]
     self.assertEqual(ufo['a'].lib.get('public.markColor'),
                      '0.9569,0,0.5412,0.0039')
     self.assertEqual(ufo['b'].lib.get('public.markColor'), '0.97,1,0,1')
     self.assertEqual(ufo['c'].lib.get('public.markColor'), None)
     self.assertEqual(ufo['d'].lib.get('public.markColor'), None)
Ejemplo n.º 7
0
 def test_GDEF(self):
     font = generate_minimal_font()
     for glyph in ('space', 'A', 'A.alt', 'wigglylinebelowcomb',
                   'wigglylinebelowcomb.alt', 'fi', 'fi.alt', 't_e_s_t',
                   't_e_s_t.alt'):
         add_glyph(font, glyph)
     add_anchor(font, 'A', 'bottom', 300, -10)
     add_anchor(font, 'wigglylinebelowcomb', '_bottom', 100, 40)
     add_anchor(font, 'fi', 'caret_1', 150, 0)
     add_anchor(font, 't_e_s_t.alt', 'caret_1', 200, 0)
     add_anchor(font, 't_e_s_t.alt', 'caret_2', 400, 0)
     add_anchor(font, 't_e_s_t.alt', 'caret_3', 600, 0)
     ufo = to_ufos(font)[0]
     self.assertEqual(ufo.features.text.splitlines(), [
         'table GDEF {',
         '  # automatic',
         '  GlyphClassDef',
         '    [A], # Base',
         '    [fi t_e_s_t.alt], # Liga',
         '    [wigglylinebelowcomb wigglylinebelowcomb.alt], # Mark',
         '    ;',
         '  LigatureCaretByPos fi 150;',
         '  LigatureCaretByPos t_e_s_t.alt 200 400 600;',
         '} GDEF;',
     ])
Ejemplo n.º 8
0
 def test_subCategory(self):
     font = generate_minimal_font()
     add_glyph(font, 'foo')['subCategory'] = 'Nonspacing'
     add_glyph(font, 'bar')
     ufo = to_ufos(font)[0]
     subCategory_key = GLYPHLIB_PREFIX + 'subCategory'
     self.assertEqual(ufo['foo'].lib.get(subCategory_key), 'Nonspacing')
     self.assertFalse(subCategory_key in ufo['bar'].lib)
Ejemplo n.º 9
0
 def test_category(self):
     font = generate_minimal_font()
     add_glyph(font, 'foo')['category'] = 'Mark'
     add_glyph(font, 'bar')
     ufo = to_ufos(font)[0]
     category_key = GLYPHLIB_PREFIX + 'category'
     self.assertEqual(ufo['foo'].lib.get(category_key), 'Mark')
     self.assertFalse(category_key in ufo['bar'].lib)
Ejemplo n.º 10
0
 def test_set_glyphOrder_no_custom_param(self):
     font = generate_minimal_font()
     add_glyph(font, 'C')
     add_glyph(font, 'B')
     add_glyph(font, 'A')
     add_glyph(font, 'Z')
     glyphOrder = to_ufos(font)[0].lib[PUBLIC_PREFIX + 'glyphOrder']
     self.assertEqual(glyphOrder, ['C', 'B', 'A', 'Z'])
Ejemplo n.º 11
0
 def test_GDEF_fractional_caret_position(self):
     # Some Glyphs sources happen to contain fractional caret positions.
     # In the Adobe feature file syntax (and binary OpenType GDEF tables),
     # caret positions must be integers.
     font = generate_minimal_font()
     add_glyph(font, 'fi')
     add_anchor(font, 'fi', 'caret_1', 499.9876, 0)
     self.assertIn('LigatureCaretByPos fi 500;',
                   to_ufos(font)[0].features.text)
Ejemplo n.º 12
0
    def test_warn_no_version(self):
        """Test that a warning is printed when app version is missing."""

        font = generate_minimal_font()
        font.appVersion = "0"
        with CapturingLogHandler(builder.logger, "WARNING") as captor:
            to_ufos(font)
        self.assertEqual(
            len([r for r in captor.records if "outdated version" in r.msg]), 1)
Ejemplo n.º 13
0
 def test_set_glyphOrder_with_custom_param(self):
     font = generate_minimal_font()
     font.customParameters['glyphOrder'] = ['A', 'B', 'C']
     add_glyph(font, 'C')
     add_glyph(font, 'B')
     add_glyph(font, 'A')
     # glyphs outside glyphOrder are appended at the end
     add_glyph(font, 'Z')
     glyphOrder = to_ufos(font)[0].lib[PUBLIC_PREFIX + 'glyphOrder']
     self.assertEqual(glyphOrder, ['A', 'B', 'C', 'Z'])
Ejemplo n.º 14
0
 def test_GDEF_custom_category_subCategory(self):
     font = generate_minimal_font()
     add_glyph(font, 'foo')['subCategory'] = 'Ligature'
     add_anchor(font, 'foo', 'top', 400, 1000)
     bar = add_glyph(font, 'bar')
     bar['category'], bar['subCategory'] = 'Mark', 'Nonspacing'
     baz = add_glyph(font, 'baz')
     baz['category'], baz['subCategory'] = 'Mark', 'Spacing Combining'
     features = to_ufos(font)[0].features.text
     self.assertIn('[foo], # Liga', features)
     self.assertIn('[bar baz], # Mark', features)
Ejemplo n.º 15
0
 def test_postscript_name_from_glyph_name(self):
     font = generate_minimal_font()
     # in GlyphData (and AGLFN) without a 'production' name
     add_glyph(font, 'A')
     # not in GlyphData, no production name
     add_glyph(font, 'foobar')
     # in GlyphData with a 'production' name
     add_glyph(font, 'C-fraktur')
     ufo = to_ufos(font)[0]
     postscriptNames = ufo.lib.get('public.postscriptNames')
     self.assertEqual(postscriptNames, {'C-fraktur': 'uni212D'})
Ejemplo n.º 16
0
    def test_glyph_lib_metricsKeys(self):
        font = generate_minimal_font()
        glyph = add_glyph(font, "x")
        glyph.leftMetricsKey = "y"
        glyph.rightMetricsKey = "z"
        assert glyph.widthMetricsKey is None

        ufo = to_ufos(font)[0]

        self.assertEqual(ufo["x"].lib[GLYPHLIB_PREFIX + "leftMetricsKey"], "y")
        self.assertEqual(ufo["x"].lib[GLYPHLIB_PREFIX + "rightMetricsKey"],
                         "z")
        self.assertNotIn(GLYPHLIB_PREFIX + "widthMetricsKey", ufo["x"].lib)
Ejemplo n.º 17
0
    def test_set_blue_values(self):
        """Test that blue values are set correctly from alignment zones."""

        data_in = [GSAlignmentZone(pos=500, size=15), GSAlignmentZone(pos=400, size=-15), GSAlignmentZone(pos=0, size=-15), GSAlignmentZone(pos=-200, size=15), GSAlignmentZone(pos=-300, size=-15)]
        expected_blue_values = [-200, -185, -15, 0, 500, 515]
        expected_other_blues = [-315, -300, 385, 400]

        font = generate_minimal_font()
        font.masters[0].alignmentZones = data_in
        ufo = to_ufos(font)[0]

        self.assertEqual(ufo.info.postscriptBlueValues, expected_blue_values)
        self.assertEqual(ufo.info.postscriptOtherBlues, expected_other_blues)
Ejemplo n.º 18
0
    def test_variation_font_origin(self):
        font = generate_minimal_font()
        name = 'Variation Font Origin'
        value = 'Light'
        font.customParameters[name] = value

        ufos, instances = to_ufos(font, include_instances=True)

        for ufo in ufos:
            key = GLYPHS_PREFIX + name
            self.assertIn(key, ufo.lib)
            self.assertEqual(ufo.lib[key], value)
        self.assertIn(name, instances)
        self.assertEqual(instances[name], value)
Ejemplo n.º 19
0
    def test_glyph_lib_Export(self):
        font = generate_minimal_font()
        glyph = add_glyph(font, "a")

        self.assertEqual(glyph.export, True)

        ufo = to_ufos(font)[0]

        self.assertNotIn(GLYPHLIB_PREFIX + "Export", ufo["a"].lib)

        glyph.export = False
        ufo = to_ufos(font)[0]

        self.assertEqual(ufo["a"].lib[GLYPHLIB_PREFIX + "Export"], False)
Ejemplo n.º 20
0
    def test_propagate_anchors(self):
        """Test anchor propagation for some relatively complicated cases."""

        font = generate_minimal_font()

        glyphs = (
            ('sad', [], [('bottom', 50, -50), ('top', 50, 150)]),
            ('dotabove', [], [('top', 0, 150), ('_top', 0, 100)]),
            ('dotbelow', [], [('bottom', 0, -50), ('_bottom', 0, 0)]),
            ('dad', [('sad', 0, 0), ('dotabove', 50, 50)], []),
            ('dadDotbelow', [('dad', 0, 0), ('dotbelow', 50, -50)], []),
            ('yod', [], [('bottom', 50, -50)]),
            ('yodyod', [('yod', 0, 0), ('yod', 100, 0)], []),
        )
        for name, component_data, anchor_data in glyphs:
            glyph = add_glyph(font, name)
            for n, x, y, in anchor_data:
                add_anchor(font, name, n, x, y)
            for n, x, y in component_data:
                add_component(font, name, n, (1, 0, 0, 1, x, y))

        ufos = to_ufos(font)
        ufo = ufos[0]

        glyph = ufo['dadDotbelow']
        self.assertEqual(len(glyph.anchors), 2)
        # check propagated anchors are appended in a deterministic order
        self.assertEqual(
            [anchor.name for anchor in glyph.anchors],
            ['bottom', 'top']
        )
        for anchor in glyph.anchors:
            self.assertEqual(anchor.x, 50)
            if anchor.name == 'bottom':
                self.assertEqual(anchor.y, -100)
            else:
                self.assertEqual(anchor.name, 'top')
                self.assertEqual(anchor.y, 200)

        glyph = ufo['yodyod']
        self.assertEqual(len(glyph.anchors), 2)
        for anchor in glyph.anchors:
            self.assertEqual(anchor.y, -50)
            if anchor.name == 'bottom_1':
                self.assertEqual(anchor.x, 50)
            else:
                self.assertEqual(anchor.name, 'bottom_2')
                self.assertEqual(anchor.x, 150)
Ejemplo n.º 21
0
 def test_supplementary_layers(self):
     """Test sub layers."""
     font = generate_minimal_font()
     glyph = GSGlyph(name="a")
     font.glyphs.append(glyph)
     layer = GSLayer()
     layer.layerId = font.masters[0].id
     layer.width = 0
     glyph.layers.append(layer)
     sublayer = GSLayer()
     sublayer.associatedMasterId = font.masters[0].id
     sublayer.width = 0
     sublayer.name = "SubLayer"
     glyph.layers.append(sublayer)
     ufo = to_ufos(font)[0]
     self.assertEqual([l.name for l in ufo.layers],
                      ["public.default", "SubLayer"])
Ejemplo n.º 22
0
    def test_minimal_data(self):
        """Test the minimal data that must be provided to generate UFOs, and in
        some cases that additional redundant data is not set.
        """

        font = generate_minimal_font()
        family_name = font.familyName
        ufos = to_ufos(font)
        self.assertEqual(len(ufos), 1)

        ufo = ufos[0]
        self.assertEqual(len(ufo), 0)
        self.assertEqual(ufo.info.familyName, family_name)
        # self.assertEqual(ufo.info.styleName, 'Regular')
        self.assertEqual(ufo.info.versionMajor, 1)
        self.assertEqual(ufo.info.versionMinor, 0)
        self.assertIsNone(ufo.info.openTypeNameVersion)
Ejemplo n.º 23
0
    def test_fail_during_anchor_propagation(self):
        """Fix https://github.com/googlei18n/glyphsLib/issues/317"""
        font = generate_minimal_font()

        glyphs = (
            # This glyph has components that don't exist in the font
            ('yodyod', [('yod', 0, 0), ('yod', 100, 0)], []),
        )
        for name, component_data, anchor_data in glyphs:
            add_glyph(font, name)
            for n, x, y, in anchor_data:
                add_anchor(font, name, n, x, y)
            for n, x, y in component_data:
                add_component(font, name, n, (1, 0, 0, 1, x, y))

        # We just want the call to `to_ufos` to not crash
        assert to_ufos(font)
Ejemplo n.º 24
0
 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)
Ejemplo n.º 25
0
    def test_load_kerning(self):
        """Test that kerning conflicts are resolved correctly.

        Correct resolution is defined as such: the last time a pair is found in
        a kerning rule, that rule is used for the pair.
        """

        font = generate_minimal_font()

        # generate classes 'A': ['A', 'a'] and 'V': ['V', 'v']
        for glyph_name in ('A', 'a', 'V', 'v'):
            glyph = add_glyph(font, glyph_name)
            glyph.rightKerningGroup = glyph_name.upper()
            glyph.leftKerningGroup = glyph_name.upper()

        # classes are referenced in Glyphs kerning using old MMK names
        font.kerning = {
            font.masters[0].id:
            collections.OrderedDict((
                ('@MMK_L_A',
                 collections.OrderedDict((
                     ('@MMK_R_V', -250),
                     ('v', -100),
                 ))),
                ('a', collections.OrderedDict((('@MMK_R_V', 100), ))),
            ))
        }

        ufos = to_ufos(font)
        ufo = ufos[0]

        # these rules should be obvious
        self.assertEqual(ufo.kerning['public.kern1.A', 'public.kern2.V'], -250)
        self.assertEqual(ufo.kerning['a', 'public.kern2.V'], 100)

        # this rule results from breaking up (kern1.A, v, -100)
        # due to conflict with (a, kern2.V, 100)
        self.assertEqual(ufo.kerning['A', 'v'], -100)
Ejemplo n.º 26
0
    def test_mark_nonspacing_zero_width(self):
        font = generate_minimal_font()

        add_glyph(font, 'dieresiscomb').layers[0].width = 100

        foo = add_glyph(font, 'foo')
        foo.category = 'Mark'
        foo.subCategory = 'Nonspacing'
        foo.layers[0].width = 200

        bar = add_glyph(font, 'bar')
        bar.category = 'Mark'
        bar.subCategory = 'Nonspacing'
        bar.layers[0].width = 0

        ufo = to_ufos(font)[0]

        originalWidth_key = GLYPHLIB_PREFIX + 'originalWidth'
        self.assertEqual(ufo['dieresiscomb'].width, 0)
        self.assertEqual(ufo['dieresiscomb'].lib.get(originalWidth_key), 100)
        self.assertEqual(ufo['foo'].width, 0)
        self.assertEqual(ufo['foo'].lib.get(originalWidth_key), 200)
        self.assertEqual(ufo['bar'].width, 0)
        self.assertFalse(originalWidth_key in ufo['bar'].lib)
Ejemplo n.º 27
0
 def test_coerce_to_bool(self):
     font = generate_minimal_font()
     font.customParameters['Disable Last Change'] = 'Truthy'
     ufo = to_ufos(font)[0]
     self.assertEqual(True, ufo.lib[GLYPHS_PREFIX + 'disablesLastChange'])
Ejemplo n.º 28
0
 def test_lib_custom(self):
     font = generate_minimal_font()
     font.masters[0].customName = 'FooBar'
     ufo = to_ufos(font)[0]
     self.assertEqual(ufo.lib[GLYPHS_PREFIX + 'customName'], 'FooBar')
Ejemplo n.º 29
0
 def test_lib_no_custom(self):
     font = generate_minimal_font()
     ufo = to_ufos(font)[0]
     self.assertFalse(GLYPHS_PREFIX + 'customName' in ufo.lib)
Ejemplo n.º 30
0
 def test_lib_width(self):
     font = generate_minimal_font()
     font.masters[0].width = 'Condensed'
     ufo = to_ufos(font)[0]
     self.assertEqual(ufo.lib[GLYPHS_PREFIX + 'width'], 'Condensed')