Beispiel #1
0
def test_font_equality(datadir):
    font1 = Font.open(datadir / "UbuTestData.ufo")
    font2 = Font.open(datadir / "UbuTestData.ufo")

    assert font1 == font2

    class SubFont(Font):
        pass

    font3 = SubFont.open(datadir / "UbuTestData.ufo")
    assert font1 != font3
Beispiel #2
0
def test_object_lib_prune(tmp_path: Path) -> None:
    ufo = Font()

    ufo.info.guidelines = [Guideline(x=100), Guideline(y=200)]
    _ = ufo.objectLib(ufo.info.guidelines[0])
    guideline_lib = ufo.objectLib(ufo.info.guidelines[1])
    guideline_lib["com.test.foo"] = 1234
    ufo.lib["public.objectLibs"]["aaaa"] = {"1": 1}

    ufo.newGlyph("component")
    glyph = ufo.newGlyph("test")

    glyph.guidelines = [Guideline(x=300), Guideline(y=400)]
    _ = glyph.objectLib(glyph.guidelines[0])
    glyph_guideline_lib = glyph.objectLib(glyph.guidelines[1])
    glyph_guideline_lib["com.test.foo"] = 4321
    glyph.lib["public.objectLibs"]["aaaa"] = {"1": 1}

    ufo.save(tmp_path / "test.ufo")

    # Roundtrip
    ufo_reload = Font.open(tmp_path / "test.ufo")
    assert set(ufo_reload.lib["public.objectLibs"].keys()) == {
        ufo.info.guidelines[1].identifier
    }
    assert set(ufo_reload["test"].lib["public.objectLibs"].keys()) == {
        glyph.guidelines[1].identifier
    }

    # Empty object libs are pruned from objectLibs, but the identifiers stay.
    assert ufo.info.guidelines[0].identifier is not None
    assert glyph.guidelines[0].identifier is not None
Beispiel #3
0
def test_json_loads(datadir: pathlib.Path) -> None:
    data = json.loads((datadir / "MutatorSansBoldCondensed.json").read_bytes())

    expected = Font.open(datadir / "MutatorSansBoldCondensed.ufo")
    # need to get rid of CR/LF newlines that sneak in the features.fea when
    # opening the UFO on Windows
    expected.features.normalize_newlines()

    assert structure(data, Font) == expected
Beispiel #4
0
def test_nondefault_layer_name(ufo_UbuTestData, tmp_path):
    font = ufo_UbuTestData

    font.layers.renameLayer("public.default", "abc")
    font.save(tmp_path / "abc.ufo")
    font2 = Font.open(tmp_path / "abc.ufo")

    assert font2.layers.defaultLayer.name == "abc"
    assert font2.layers.defaultLayer is font2.layers["abc"]
Beispiel #5
0
def test_object_lib_roundtrip(tmp_path):
    ufo = Font()

    ufo.info.guidelines = [Guideline(x=100), Guideline(y=200)]
    guideline_lib = ufo.objectLib(ufo.info.guidelines[1])
    guideline_lib["com.test.foo"] = 1234

    ufo.newGlyph("component")
    glyph = ufo.newGlyph("test")

    glyph.guidelines = [Guideline(x=300), Guideline(y=400)]
    glyph_guideline_lib = glyph.objectLib(glyph.guidelines[1])
    glyph_guideline_lib["com.test.foo"] = 4321

    glyph.anchors = [Anchor(x=1, y=2, name="top"), Anchor(x=3, y=4, name="bottom")]
    anchor_lib = glyph.objectLib(glyph.anchors[1])
    anchor_lib["com.test.anchorTool"] = True

    pen = glyph.getPen()
    pen.moveTo((0, 0))
    pen.lineTo((100, 200))
    pen.lineTo((200, 400))
    pen.closePath()
    pen.moveTo((1000, 1000))
    pen.lineTo((1000, 2000))
    pen.lineTo((2000, 4000))
    pen.closePath()
    pen.addComponent("component", (1, 0, 0, 1, 0, 0))
    pen.addComponent("component", (1, 0, 0, 1, 0, 0))

    contour_lib = glyph.objectLib(glyph.contours[0])
    contour_lib["com.test.foo"] = "abc"
    point_lib = glyph.objectLib(glyph.contours[1].points[0])
    point_lib["com.test.foo"] = "abc"
    component_lib = glyph.objectLib(glyph.components[0])
    component_lib["com.test.foo"] = "abc"

    ufo.save(tmp_path / "test.ufo")

    # Roundtrip
    ufo_reload = Font.open(tmp_path / "test.ufo")

    reload_guideline_lib = ufo_reload.objectLib(ufo_reload.info.guidelines[1])
    reload_glyph = ufo_reload["test"]
    reload_glyph_guideline_lib = reload_glyph.objectLib(reload_glyph.guidelines[1])
    reload_anchor_lib = reload_glyph.objectLib(reload_glyph.anchors[1])
    reload_contour_lib = reload_glyph.objectLib(reload_glyph.contours[0])
    reload_point_lib = reload_glyph.objectLib(reload_glyph.contours[1].points[0])
    reload_component_lib = reload_glyph.objectLib(reload_glyph.components[0])

    assert reload_guideline_lib == guideline_lib
    assert reload_glyph_guideline_lib == glyph_guideline_lib
    assert reload_anchor_lib == anchor_lib
    assert reload_contour_lib == contour_lib
    assert reload_point_lib == point_lib
    assert reload_component_lib == component_lib
Beispiel #6
0
def test_json_dumps(datadir: pathlib.Path) -> None:
    font = Font.open(datadir / "MutatorSansBoldCondensed.ufo")
    # need to get rid of CR/LF newlines that sneak in the features.fea when
    # opening the UFO on Windows
    font.features.normalize_newlines()

    data = unstructure(font)

    expected = (datadir / "MutatorSansBoldCondensed.json").read_text()

    assert json.dumps(data, indent=2, sort_keys=True) == expected
Beispiel #7
0
def test_woff_metadata(datadir: Path, tmp_path: Path) -> None:
    # The WoffMetadataTest.ufo contains all the WOFF metadata, here we check
    # that ufoLib validators accept the data and can read/write fontinfo.plist.
    input_path = datadir / "WoffMetadataTest.ufo"
    output_path = tmp_path / "WoffMetadataTest.ufo"

    font = Font.open(input_path, validate=True)
    font.save(output_path, validate=True)

    assert (input_path / "fontinfo.plist").read_text("utf-8") == ((
        output_path / "fontinfo.plist").read_text("utf-8"))
Beispiel #8
0
def test_composite_margin_roundtrip(datadir: Path) -> None:
    msans = Font.open(datadir / "MutatorSansBoldCondensed.ufo")

    comma = msans["comma"]

    assert comma.getLeftMargin(msans) == 30
    assert comma.getRightMargin(msans) == 30
    assert comma.width == 250

    # Quotedblleft consists of two inverted commas:
    quotedblleft = msans["quotedblleft"]

    assert quotedblleft.getLeftMargin(msans) == 30
    assert quotedblleft.getRightMargin(msans) == 30
    assert quotedblleft.width == 480

    # Now change comma and verify indirect change in quotedblleft.
    comma.setLeftMargin(27, msans)
    comma.setRightMargin(27, msans)

    assert comma.getLeftMargin(msans) == 27
    assert comma.getRightMargin(msans) == 27
    assert comma.width == 244

    assert quotedblleft.getLeftMargin(msans) == 33
    assert quotedblleft.getRightMargin(msans) == 27
    assert quotedblleft.width == 480

    # Changing margins of quotedblleft should not affect comma.
    quotedblleft.setLeftMargin(23, msans)
    quotedblleft.setRightMargin(22, msans)

    assert comma.getLeftMargin(msans) == 27
    assert comma.getRightMargin(msans) == 27
    assert comma.width == 244

    # Quotedblleft should however have the exact margins we gave above.
    assert quotedblleft.getLeftMargin(msans) == 23
    assert quotedblleft.getRightMargin(msans) == 22
    assert quotedblleft.width == 465