Exemple #1
0
def test_masters_have_user_locations_string(ufo_module):
    """Test that stringified Axis Locations are converted.

    Some versions of Glyph store a string instead of an int.
    """
    font = to_glyphs([ufo_module.Font(), ufo_module.Font()])
    font.customParameters["Axes"] = [{"Tag": "opsz", "Name": "Optical"}]
    font.masters[0].weightValue = 0
    font.masters[0].customParameters["Axis Location"] = [{
        "Axis": "Optical",
        "Location": 13
    }]
    font.masters[1].weightValue = 1000
    font.masters[1].customParameters["Axis Location"] = [{
        "Axis": "Optical",
        "Location": "100"
    }]

    doc = to_designspace(font, ufo_module=ufo_module)
    assert doc.axes[0].map == [(13, 0), (100, 1000)]

    font = to_glyphs(doc)
    assert font.masters[0].customParameters["Axis Location"] == [{
        "Axis": "Optical",
        "Location": 13
    }]
    assert font.masters[1].customParameters["Axis Location"] == [{
        "Axis":
        "Optical",
        "Location":
        100
    }]
Exemple #2
0
def test_only_background(ufo_module):
    ufo = ufo_module.Font()
    background = ufo.newLayer("public.background")
    background.newGlyph("a")

    # Check that it does not crash
    to_glyphs([ufo])
Exemple #3
0
def test_roundtrip_disabled_feature():
    font = to_glyphs([defcon.Font()])
    feature = classes.GSFeature(name="ccmp")
    feature.code = dedent("""\
        sub a by a.ss03;
        sub b by b.ss03;
        sub c by c.ss03;
    """)
    feature.disabled = True
    font.features.append(feature)

    ufo, = to_ufos(font)
    assert ufo.features.text == dedent('''\
        feature ccmp {
        # disabled
        #sub a by a.ss03;
        #sub b by b.ss03;
        #sub c by c.ss03;
        } ccmp;
    ''')

    font_r = to_glyphs([ufo])
    assert len(font_r.features) == 1
    feature_r = font_r.features[0]
    assert feature_r.name == "ccmp"
    assert feature_r.code == feature.code
    assert feature_r.disabled is True

    font_rr = to_glyphs(to_ufos(font_r))
    assert len(font_rr.features) == 1
    feature_rr = font_rr.features[0]
    assert feature_rr.name == "ccmp"
    assert feature_rr.code == feature.code
    assert feature_rr.disabled is True
def test_designspace_generation_bracket_roundtrip_psnames(datadir, ufo_module):
    with open(str(datadir.join("PSNames.glyphs"))) as f:
        font = glyphsLib.load(f)
    designspace: DesignSpaceDocument = to_designspace(font, ufo_module=ufo_module)

    assert designspace.findDefault().font.lib["public.postscriptNames"] == {
        "a-cy": "uni0430",
        "a-cy.BRACKET.18": "uni0430.BRACKET.18",
        "a-cy.alt": "uni0430.alt",
    }

    font_rt = to_glyphs(designspace)
    designspace_rt = to_designspace(font_rt, ufo_module=ufo_module)

    assert designspace_rt.findDefault().font.lib["public.postscriptNames"] == {
        "a-cy": "uni0430",
        "a-cy.BRACKET.18": "uni0430.BRACKET.18",
        "a-cy.alt": "uni0430.alt",
    }

    font_rt2 = to_glyphs(designspace_rt)
    designspace_rt2 = to_designspace(font_rt2, ufo_module=ufo_module)

    assert designspace_rt2.findDefault().font.lib["public.postscriptNames"] == {
        "a-cy": "uni0430",
        "a-cy.BRACKET.18": "uni0430.BRACKET.18",
        "a-cy.alt": "uni0430.alt",
    }
Exemple #5
0
def test_background_before_foreground(ufo_module):
    ufo = ufo_module.Font()
    ufo.newGlyph("a")
    background = ufo.newLayer("public.background")
    background.newGlyph("a")

    ufo.layers.layerOrder = ["public.background", "public.default"]

    # Check that it does not crash
    to_glyphs([ufo])
Exemple #6
0
def test_masters_have_user_locations():
    """Test the new axis definition with custom parameters.
    See https://github.com/googlei18n/glyphsLib/issues/280.

    For tests about the previous system with weight/width/custom,
    see `tests/builder/interpolation_test.py`.
    """
    # Get a font with two masters
    font = to_glyphs([defcon.Font(), defcon.Font()])
    font.customParameters['Axes'] = [{
        'Tag': 'opsz',
        'Name': 'Optical',
    }]
    # There is only one axis, so the design location is stored in the weight
    font.masters[0].weightValue = 0
    # The user location is stored as a custom parameter
    font.masters[0].customParameters['Axis Location'] = [{
        'Axis': 'Optical',
        'Location': 13,
    }]
    font.masters[1].weightValue = 1000
    font.masters[1].customParameters['Axis Location'] = [{
        'Axis': 'Optical',
        'Location': 100,
    }]

    doc = to_designspace(font)
    assert len(doc.axes) == 1
    assert doc.axes[0].map == [
        (13, 0),
        (100, 1000),
    ]
    assert len(doc.sources) == 2
    assert doc.sources[0].location == {'Optical': 0}
    assert doc.sources[1].location == {'Optical': 1000}

    font = to_glyphs(doc)
    assert font.customParameters['Axes'] == [{
        'Tag': 'opsz',
        'Name': 'Optical',
    }]
    assert font.masters[0].weightValue == 0
    assert font.masters[0].customParameters['Axis Location'] == [{
        'Axis':
        'Optical',
        'Location':
        13,
    }]
    assert font.masters[1].weightValue == 1000
    assert font.masters[1].customParameters['Axis Location'] == [{
        'Axis':
        'Optical',
        'Location':
        100,
    }]
Exemple #7
0
def test_axis_mapping(ufo_module):
    font = to_glyphs([
        ufo_module.Font(),
        ufo_module.Font(),
        ufo_module.Font(),
        ufo_module.Font()
    ])
    font.masters[0].weightValue = 0
    font.masters[0].widthValue = 100
    font.masters[1].weightValue = 1000
    font.masters[1].widthValue = 100

    font.masters[2].weightValue = 0
    font.masters[2].widthValue = 75
    font.masters[3].weightValue = 1000
    font.masters[3].widthValue = 75

    wght_mapping = [(100, 0), (400, 350), (900, 1000)]
    wdth_mapping = [(75, 75), (100, 100)]

    axis_mappings = {
        "wght": {str(float(k)): v
                 for k, v in wght_mapping},
        "wdth": {str(float(k)): v
                 for k, v in wdth_mapping},
    }

    font.customParameters["Axis Mappings"] = axis_mappings
    # When we convert to a designspace, the wdth mapping is removed because
    # it isn't needed.
    doc = to_designspace(font, ufo_module=ufo_module)

    assert doc.axes[0].name == "Weight"
    assert doc.axes[0].minimum == 100
    assert doc.axes[0].default == 100
    assert doc.axes[0].maximum == 900
    assert doc.axes[0].map == wght_mapping

    assert doc.axes[1].name == "Width"
    assert doc.axes[1].minimum == 75
    assert doc.axes[0].default == 100
    assert doc.axes[1].maximum == 100
    assert doc.axes[1].map != wdth_mapping
    assert doc.axes[1].map == []

    # When we convert back to glyphs, the wdth mapping isn't present because
    # it was removed during the designspace conversion.
    font = to_glyphs(doc)
    axis_mappings["wdth"] = {}
    assert font.customParameters["Axis Mappings"] == axis_mappings
def test_designspace_generation_regular_different_family_names(tmpdir):
    ufo_Lt = defcon.Font()
    ufo_Lt.info.familyName = "CoolFoundry Examplary Serif Light"
    ufo_Lt.info.styleName = "Regular"
    ufo_Lt.info.openTypeOS2WeightClass = 300

    ufo_Rg = defcon.Font()
    ufo_Rg.info.familyName = "CoolFoundry Examplary Serif"
    ufo_Rg.info.styleName = "Regular"
    ufo_Rg.info.openTypeOS2WeightClass = 400

    # Different family names are not allowed
    # REVIEW: reasonable requirement?
    with pytest.raises(Exception):
        to_glyphs([ufo_Lt, ufo_Rg])
def test_dont_copy_advance_to_the_background_unless_it_was_there(tmpdir):
    ufo = defcon.Font()
    bg = ufo.newLayer('public.background')

    fg_a = ufo.newGlyph('a')
    fg_a.width = 100
    bg_a = bg.newGlyph('a')

    fg_b = ufo.newGlyph('b')
    fg_b.width = 200
    bg_b = bg.newGlyph('b')
    bg_b.width = 300

    fg_c = ufo.newGlyph('c')
    fg_c.width = 400
    bg_c = bg.newGlyph('c')
    bg_c.width = 400

    font = to_glyphs([ufo])
    path = os.path.join(str(tmpdir), 'test.glyphs')
    font.save(path)
    saved_font = classes.GSFont(path)

    for font in [font, saved_font]:
        ufo, = to_ufos(font)

        assert ufo['a'].width == 100
        assert ufo.layers['public.background']['a'].width == 0
        assert ufo['b'].width == 200
        assert ufo.layers['public.background']['b'].width == 300
        assert ufo['c'].width == 400
        assert ufo.layers['public.background']['c'].width == 400
def test_designspace_source_locations(tmpdir):
    """Check that opening UFOs from their source descriptor works with both
    the filename and the path attributes.
    """
    designspace_path = os.path.join(str(tmpdir), 'test.designspace')
    light_ufo_path = os.path.join(str(tmpdir), 'light.ufo')
    bold_ufo_path = os.path.join(str(tmpdir), 'bold.ufo')

    designspace = DesignSpaceDocument()
    light_source = designspace.newSourceDescriptor()
    light_source.filename = 'light.ufo'
    designspace.addSource(light_source)
    bold_source = designspace.newSourceDescriptor()
    bold_source.path = bold_ufo_path
    designspace.addSource(bold_source)
    designspace.write(designspace_path)

    light = defcon.Font()
    light.info.ascender = 30
    light.save(light_ufo_path)

    bold = defcon.Font()
    bold.info.ascender = 40
    bold.save(bold_ufo_path)

    designspace = DesignSpaceDocument()
    designspace.read(designspace_path)

    font = to_glyphs(designspace)

    assert len(font.masters) == 2
    assert font.masters[0].ascender == 30
    assert font.masters[1].ascender == 40
def test_custom_featureWriters_in_designpace_lib(tmpdir, ufo_module):
    """Test that we can roundtrip custom user-defined ufo2ft featureWriters
    settings that are stored in the designspace lib or GSFont.userData.
    """
    font = classes.GSFont()
    font.masters.append(classes.GSFontMaster())
    kern = classes.GSFeature(name="kern", code="pos a b 100;")
    font.features.append(kern)
    customFeatureWriters = list(DEFAULT_FEATURE_WRITERS) + [{
        "class":
        "MyCustomWriter",
        "module":
        "myCustomWriter"
    }]
    font.userData[UFO2FT_FEATURE_WRITERS_KEY] = customFeatureWriters

    designspace = to_designspace(font, ufo_module=ufo_module)
    path = str(tmpdir / "test.designspace")
    designspace.write(path)
    for source in designspace.sources:
        source.font.save(str(tmpdir / source.filename))

    designspace2 = DesignSpaceDocument.fromfile(path)

    assert UFO2FT_FEATURE_WRITERS_KEY in designspace2.lib
    assert designspace2.lib[UFO2FT_FEATURE_WRITERS_KEY] == customFeatureWriters

    font2 = to_glyphs(designspace2, ufo_module=ufo_module)

    assert len(font2.userData) == 1
    assert font2.userData[UFO2FT_FEATURE_WRITERS_KEY] == customFeatureWriters
def test_default_featureWriters_in_designspace_lib(tmpdir, ufo_module):
    """Test that the glyphsLib custom featureWriters settings (with mode="append")
    are exported to the designspace lib whenever a GSFont contains a manual 'kern'
    feature. And that they are not imported back to GSFont.userData if they are
    the same as the default value.
    """
    font = classes.GSFont()
    font.masters.append(classes.GSFontMaster())
    kern = classes.GSFeature(name="kern", code="pos a b 100;")
    font.features.append(kern)

    designspace = to_designspace(font, ufo_module=ufo_module)
    path = str(tmpdir / "test.designspace")
    designspace.write(path)
    for source in designspace.sources:
        source.font.save(str(tmpdir / source.filename))

    designspace2 = DesignSpaceDocument.fromfile(path)

    assert UFO2FT_FEATURE_WRITERS_KEY in designspace2.lib
    assert designspace2.lib[
        UFO2FT_FEATURE_WRITERS_KEY] == DEFAULT_FEATURE_WRITERS

    font2 = to_glyphs(designspace2, ufo_module=ufo_module)

    assert not len(font2.userData)
    assert len([f for f in font2.features if f.name == "kern"]) == 1
def test_designspace_generation_bracket_no_export_glyph(datadir):
    with open(str(datadir.join("BracketTestFont2.glyphs"))) as f:
        font = glyphsLib.load(f)

    font.glyphs["E"].export = False

    designspace = to_designspace(font, write_skipexportglyphs=True)

    assert "E" in designspace.lib.get("public.skipExportGlyphs")

    for source in designspace.sources:
        assert "E.REV_BRACKET.570" not in source.font
        assert "E.BRACKET.630" not in source.font

    for rule in designspace.rules:
        assert "E" not in {g for g in itertools.chain(*rule.subs)}

    font_rt = to_glyphs(designspace)

    assert "E" in font_rt.glyphs
    assert {l.name
            for l in font_rt.glyphs["E"].layers} == {
                "Regular",
                "Regular [630]",
                "Bold",
                "Bold ]570]",
            }
def test_designspace_generation_bracket_composite_glyph(datadir):
    with open(str(datadir.join("BracketTestFont2.glyphs"))) as f:
        font = glyphsLib.load(f)

    g = font.glyphs["B"]
    for layer in g.layers:
        assert layer.components[0].name == "A"

    designspace = to_designspace(font)

    for source in designspace.sources:
        ufo = source.font
        assert "B.BRACKET.600" in ufo
        assert ufo["B"].components[0].baseGlyph == "A"
        assert ufo["B.BRACKET.600"].components[0].baseGlyph == "A.BRACKET.600"

    font_rt = to_glyphs(designspace)

    assert "B" in font_rt.glyphs

    g2 = font_rt.glyphs["B"]
    for layer in g2.layers:
        assert layer.components[0].name == "A"

    assert "B.BRACKET.600" not in font_rt.glyphs
Exemple #15
0
def roundtrip(ufo, tmpdir):
    font = to_glyphs([ufo], minimize_ufo_diffs=True)
    filename = os.path.join(str(tmpdir), 'font.glyphs')
    font.save(filename)
    font = classes.GSFont(filename)
    ufo, = to_ufos(font)
    return font, ufo
Exemple #16
0
def test_dont_copy_advance_to_the_background_unless_it_was_there(
        tmpdir, ufo_module):
    ufo = ufo_module.Font()
    bg = ufo.newLayer("public.background")

    fg_a = ufo.newGlyph("a")
    fg_a.width = 100
    bg.newGlyph("a")

    fg_b = ufo.newGlyph("b")
    fg_b.width = 200
    bg_b = bg.newGlyph("b")
    bg_b.width = 300

    fg_c = ufo.newGlyph("c")
    fg_c.width = 400
    bg_c = bg.newGlyph("c")
    bg_c.width = 400

    font = to_glyphs([ufo])
    path = os.path.join(str(tmpdir), "test.glyphs")
    font.save(path)
    saved_font = classes.GSFont(path)

    for font in [font, saved_font]:
        (ufo, ) = to_ufos(font)

        assert ufo["a"].width == 100
        assert ufo.layers["public.background"]["a"].width == 0
        assert ufo["b"].width == 200
        assert ufo.layers["public.background"]["b"].width == 300
        assert ufo["c"].width == 400
        assert ufo.layers["public.background"]["c"].width == 400
Exemple #17
0
def roundtrip(ufo, tmpdir, ufo_module):
    font = to_glyphs([ufo], minimize_ufo_diffs=True)
    filename = os.path.join(str(tmpdir), "font.glyphs")
    font.save(filename)
    font = classes.GSFont(filename)
    (ufo, ) = to_ufos(font, ufo_module=ufo_module)
    return font, ufo
Exemple #18
0
def test_groups_remain_at_top(tmpdir, ufo_module):
    ufo = ufo_module.Font()
    ufo.newGlyph("zero")
    ufo.newGlyph("zero.alt")
    fea_example = dedent("""\
        @FIG_DFLT = [zero];
        @FIG_ALT = [zero.alt];

        lookup pnum_text {
            sub @FIG_DFLT by @FIG_ALT;
        } pnum_text;

        feature pnum {
            lookup pnum_text;
        } pnum;
        """)
    ufo.features.text = fea_example

    font = to_glyphs([ufo], minimize_ufo_diffs=True)
    filename = os.path.join(str(tmpdir), "font.glyphs")
    font.save(filename)
    font = classes.GSFont(filename)
    (rtufo, ) = to_ufos(font, ufo_module=ufo_module)

    fea_rt = rtufo.features.text
    assert fea_rt.index("@FIG_DFLT") < fea_rt.index("lookup") < fea_rt.index(
        "feature")
Exemple #19
0
def test_mapping_is_same_regardless_of_axes_custom_parameter(ufo_module):
    # https://github.com/googlefonts/glyphsLib/issues/409
    # https://github.com/googlefonts/glyphsLib/issues/411

    # First, try without the custom param
    font = to_glyphs([ufo_module.Font(), ufo_module.Font(), ufo_module.Font()])
    font.masters[0].name = "ExtraLight"
    font.masters[0].weightValue = 200
    font.masters[1].name = "Regular"
    font.masters[1].weightValue = 400
    font.masters[2].name = "Bold"
    font.masters[2].weightValue = 700

    doc = to_designspace(font, ufo_module=ufo_module)
    assert doc.axes[0].minimum == 200
    assert doc.axes[0].maximum == 700
    assert doc.axes[0].map == []

    # Now with the custom parameter. Should produce the same results
    font.customParameters["Axes"] = [{"Name": "Weight", "Tag": "wght"}]

    doc = to_designspace(font, ufo_module=ufo_module)
    assert doc.axes[0].minimum == 200
    assert doc.axes[0].maximum == 700
    assert doc.axes[0].map == []
Exemple #20
0
def test_master_user_location_goes_into_os2_classes(ufo_module):
    font = to_glyphs([ufo_module.Font(), ufo_module.Font()])
    font.customParameters["Axes"] = [
        {"Tag": "wght", "Name": "Weight"},
        {"Tag": "wdth", "Name": "Width"},
    ]
    font.masters[0].weightValue = 0
    font.masters[0].widthValue = 1000
    # This master will be Light Expanded
    # as per https://docs.microsoft.com/en-gb/typography/opentype/spec/os2#uswidthclass
    font.masters[0].customParameters["Axis Location"] = [
        {"Axis": "Weight", "Location": 300},
        {"Axis": "Width", "Location": 125},
    ]
    font.masters[1].weightValue = 1000
    font.masters[1].widthValue = 0
    # This master is Black Ultra-condensed but not quite
    font.masters[1].customParameters["Axis Location"] = [
        {"Axis": "Weight", "Location": 920},  # instead of 900
        {"Axis": "Width", "Location": 55},  # instead of 50
    ]

    light, black = to_ufos(font)

    assert light.info.openTypeOS2WeightClass == 300
    assert light.info.openTypeOS2WidthClass == 7

    assert black.info.openTypeOS2WeightClass == 920
    assert black.info.openTypeOS2WidthClass == 1
def test_only_background():
    ufo = defcon.Font()
    background = ufo.newLayer('public.background')
    a_bg = background.newGlyph('a')

    # Check that it does not crash
    font = to_glyphs([ufo])
def test_info_name_records(tmpdir, ufo_module):
    ufo = ufo_module.Font()

    name_records = [
        {
            "nameID": 19,
            "platformID": 1,
            "encodingID": 0,
            "languageID": 1,
            "string": "Les cornichons sont nos amis",
        },
        {
            "nameID": 1,
            "platformID": 3,
            "encodingID": 1,
            "languageID": 0x0410,
            "string": "Illustrativo Sans",
        },
    ]

    ufo.info.openTypeNameRecords = name_records

    font = to_glyphs([ufo], minimize_ufo_diffs=True)
    filename = os.path.join(str(tmpdir), "font.glyphs")
    font.save(filename)
    font = classes.GSFont(filename)
    (ufo, ) = to_ufos(font, ufo_module=ufo_module)

    print(ufo.info.openTypeNameRecords)
    assert [dict(r) for r in ufo.info.openTypeNameRecords] == name_records
def test_warn_diff_between_designspace_and_ufos(caplog):
    ufo = defcon.Font()
    ufo.info.familyName = 'UFO Family Name'
    ufo.info.styleName = 'UFO Style Name'
    # ufo.info.styleMapFamilyName = 'UFO Stylemap Family Name'
    # ufo.info.styleMapStyleName = 'bold'

    doc = DesignSpaceDocument()
    source = doc.newSourceDescriptor()
    source.font = ufo
    source.familyName = 'DS Family Name'
    source.styleName = 'DS Style Name'
    doc.addSource(source)

    font = to_glyphs(doc, minimize_ufo_diffs=True)
    assert any(record.levelname == 'WARNING' for record in caplog.records)
    assert 'The familyName is different between the UFO and the designspace source' in caplog.text
    assert 'The styleName is different between the UFO and the designspace source' in caplog.text

    doc = to_designspace(font)
    source = doc.sources[0]

    # The UFO info will prevail
    assert ufo.info.familyName == 'UFO Family Name'
    assert ufo.info.styleName == 'UFO Style Name'
    assert source.font.info.familyName == 'UFO Family Name'
    assert source.font.info.styleName == 'UFO Style Name'
Exemple #24
0
def test_axis_with_no_mapping_does_not_error_in_roundtrip(ufo_module):
    """Tests that a custom axis without a mapping and without sources on its
    extremes does not generate an error during roundtrip. Also tests that
    during a to_glyphs, to_designspace roundtrip the min and max axis
    information is not lost.
    """
    doc = designspaceLib.DesignSpaceDocument()

    # Add a "Regular" source
    regular = doc.newSourceDescriptor()
    regular.font = ufo_module.Font()
    regular.location = {"Style": 0}
    doc.addSource(regular)

    axis = doc.newAxisDescriptor()
    axis.tag = "styl"
    axis.name = "Style"
    doc.addAxis(axis)

    # This axis spans a range of 0 to 1 but only has a source at {"Style": 0}
    # and no explicit mapping. The point of this test is to see if the min and
    # max are still the same after round tripping.
    doc.axes[0].minimum = 0
    doc.axes[0].maximum = 1
    doc.axes[0].default = 0
    doc.axes[0].map = []

    doc2 = deepcopy(doc)
    font = to_glyphs(doc2)
    doc_rt = to_designspace(font)

    assert doc_rt.axes[0].serialize() == doc.axes[0].serialize()
def test_designspace_generation_reverse_bracket_roundtrip(datadir):
    with open(str(datadir.join("BracketTestFont2.glyphs"))) as f:
        font = glyphsLib.load(f)

    g = font.glyphs["D"]

    assert {"Regular ]600]",
            "Bold ]600]"}.intersection(l.name for l in g.layers)

    designspace = to_designspace(font)

    assert designspace.rules[1].name == "BRACKET.400.600"
    assert designspace.rules[1].conditionSets == [[
        dict(name="Weight", minimum=400, maximum=600)
    ]]
    assert designspace.rules[1].subs == [("D", "D.REV_BRACKET.600")]

    for source in designspace.sources:
        ufo = source.font
        assert "D.REV_BRACKET.600" in ufo

    font_rt = to_glyphs(designspace)

    assert "D" in font_rt.glyphs

    g2 = font_rt.glyphs["D"]
    assert {"Regular ]600]",
            "Bold ]600]"}.intersection(l.name for l in g2.layers)

    assert "D.REV_BRACKET.600" not in font_rt.glyphs
Exemple #26
0
def test_warn_diff_between_designspace_and_ufos(caplog, ufo_module):
    ufo = ufo_module.Font()
    ufo.info.familyName = "UFO Family Name"
    ufo.info.styleName = "UFO Style Name"
    # ufo.info.styleMapFamilyName = 'UFO Stylemap Family Name'
    # ufo.info.styleMapStyleName = 'bold'

    doc = DesignSpaceDocument()
    source = doc.newSourceDescriptor()
    source.font = ufo
    source.familyName = "DS Family Name"
    source.styleName = "DS Style Name"
    doc.addSource(source)

    font = to_glyphs(doc, minimize_ufo_diffs=True)
    assert any(record.levelname == "WARNING" for record in caplog.records)
    assert (
        "The familyName is different between the UFO and the designspace source"
        in caplog.text)
    assert (
        "The styleName is different between the UFO and the designspace source"
        in caplog.text)

    doc = to_designspace(font, ufo_module=ufo_module)
    source = doc.sources[0]

    # The UFO info will prevail
    assert ufo.info.familyName == "UFO Family Name"
    assert ufo.info.styleName == "UFO Style Name"
    assert source.font.info.familyName == "UFO Family Name"
    assert source.font.info.styleName == "UFO Style Name"
Exemple #27
0
def test_masters_have_user_locations(ufo_module):
    """Test the new axis definition with custom parameters.
    See https://github.com/googlefonts/glyphsLib/issues/280.

    For tests about the previous system with weight/width/custom,
    see `tests/builder/interpolation_test.py`.
    """
    # Get a font with two masters
    font = to_glyphs([ufo_module.Font(), ufo_module.Font()])
    font.customParameters["Axes"] = [{"Tag": "opsz", "Name": "Optical"}]
    # There is only one axis, so the design location is stored in the weight
    font.masters[0].weightValue = 0
    # The user location is stored as a custom parameter
    font.masters[0].customParameters["Axis Location"] = [{
        "Axis": "Optical",
        "Location": 13
    }]
    font.masters[1].weightValue = 1000
    font.masters[1].customParameters["Axis Location"] = [{
        "Axis": "Optical",
        "Location": 100
    }]

    doc = to_designspace(font, ufo_module=ufo_module)
    assert len(doc.axes) == 1
    assert doc.axes[0].map == [(13, 0), (100, 1000)]
    assert len(doc.sources) == 2
    assert doc.sources[0].location == {"Optical": 0}
    assert doc.sources[1].location == {"Optical": 1000}

    font = to_glyphs(doc)
    assert font.customParameters["Axes"] == [{
        "Tag": "opsz",
        "Name": "Optical"
    }]
    assert font.masters[0].weightValue == 0
    assert font.masters[0].customParameters["Axis Location"] == [{
        "Axis": "Optical",
        "Location": 13
    }]
    assert font.masters[1].weightValue == 1000
    assert font.masters[1].customParameters["Axis Location"] == [{
        "Axis":
        "Optical",
        "Location":
        100
    }]
Exemple #28
0
def test_weird_kerning_roundtrip(ufo_module):
    groups = {
        "public.kern1.i": [
            "i",
            "dotlessi",
            "iacute",
            "icircumflex",
            "idieresis",
            "igrave",
            "imacron",
            "iogonek",
            "itilde",
            "f_i",
            "f_f_i",
            "fi",
            "ffi",
        ],
        "public.kern2.i": [
            "i",
            "dotlessi",
            "iacute",
            "icircumflex",
            "idieresis",
            "igrave",
            "ij",
            "imacron",
            "iogonek",
            "itilde",
            "dotlessij",
            "ijacute",
        ],
    }
    kerning = {
        ("icircumflex", "public.kern2.i"): 20,
        ("idieresis", "idieresis"): 125,
        ("idieresis", "public.kern2.i"): 35,
        ("itilde", "public.kern2.i"): 10,
        ("public.kern1.i", "icircumflex"): 15,
        ("public.kern1.i", "idieresis"): 40,
        ("public.kern1.i", "itilde"): 10,
    }
    glyphs = sorted({g for glyphs in groups.values() for g in glyphs})

    ufo = ufo_module.Font()
    for glyph in glyphs:
        ufo.newGlyph(glyph)
    for k, v in groups.items():
        ufo.groups[k] = v
    for k, v in kerning.items():
        ufo.kerning[k] = v

    font = to_glyphs([ufo])
    (ufo, ) = to_ufos(font)

    # The kerning and groups should round-trip untouched
    for name, glyphs in groups.items():
        assert set(glyphs) == set(ufo.groups[name])

    assert ufo.kerning == kerning
def test_designspace_generation_bracket_roundtrip(datadir):
    with open(str(datadir.join("BracketTestFont.glyphs"))) as f:
        font = glyphsLib.load(f)
    designspace = to_designspace(font)

    assert designspace.rules[0].name == "BRACKET.300.600"
    assert designspace.rules[0].conditionSets == [[
        dict(name="Weight", minimum=300, maximum=600)
    ]]
    assert designspace.rules[0].subs == [("x", "x.BRACKET.300")]

    assert designspace.rules[1].name == "BRACKET.300.1000"
    assert designspace.rules[1].conditionSets == [[
        dict(name="Weight", minimum=300, maximum=1000)
    ]]
    assert designspace.rules[1].subs == [("a", "a.BRACKET.300")]

    assert designspace.rules[2].name == "BRACKET.600.1000"
    assert designspace.rules[2].conditionSets == [[
        dict(name="Weight", minimum=600, maximum=1000)
    ]]
    assert designspace.rules[2].subs == [("x", "x.BRACKET.600")]

    for source in designspace.sources:
        assert "[300]" not in source.font.layers
        assert "Something [300]" not in source.font.layers
        assert "[600]" not in source.font.layers
        assert "Other [600]" not in source.font.layers
        g1 = source.font["x.BRACKET.300"]
        assert not g1.unicodes
        g2 = source.font["x.BRACKET.600"]
        assert not g2.unicodes

    font_rt = to_glyphs(designspace)
    assert "x" in font_rt.glyphs
    g1 = font_rt.glyphs["x"]
    assert len(g1.layers) == 12 and {l.name
                                     for l in g1.layers} == {
                                         "[300]",
                                         "[600]",
                                         "Bold",
                                         "Condensed Bold",
                                         "Condensed Light",
                                         "Light",
                                         "Other [600]",
                                         "Something [300]",
                                     }
    g2 = font_rt.glyphs["a"]
    assert len(g2.layers) == 8 and {l.name
                                    for l in g2.layers} == {
                                        "[300]",
                                        "Bold",
                                        "Condensed Bold",
                                        "Condensed Light",
                                        "Light",
                                    }
    assert "a.BRACKET.300" not in font_rt.glyphs
    assert "x.BRACKET.300" not in font_rt.glyphs
    assert "x.BRACKET.600" not in font_rt.glyphs
Exemple #30
0
def test_custom_stylemap_style_name(ufo_module):
    ufo = ufo_module.Font()
    ufo.info.styleMapStyleName = "bold"  # Not "regular"

    font = to_glyphs([ufo], minimize_ufo_diffs=True)
    (ufo, ) = to_ufos(font)

    assert ufo.info.styleMapStyleName == "bold"