Пример #1
0
    def test_glyph_decomposes(self):
        componentName = 'a'
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        pen.addComponent(componentName, (1, 0, 0, 1, 2, 0))
        compositeGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        pen.moveTo((2, 0))
        pen.lineTo((2, 1))
        pen.lineTo((3, 0))
        pen.closePath()
        plainGlyph = pen.glyph()

        self.assertEqual(plainGlyph, compositeGlyph)
Пример #2
0
def test_build_var(tmpdir):
    outPath = os.path.join(str(tmpdir), "test_var.ttf")

    fb, advanceWidths, nameStrings = _setupFontBuilder(True)

    pen = TTGlyphPen(None)
    pen.moveTo((100, 0))
    pen.lineTo((100, 400))
    pen.lineTo((500, 400))
    pen.lineTo((500, 000))
    pen.closePath()

    glyph = pen.glyph()

    pen = TTGlyphPen(None)
    emptyGlyph = pen.glyph()

    glyphs = {".notdef": emptyGlyph, "A": glyph, "a": glyph, ".null": emptyGlyph}
    fb.setupGlyf(glyphs)
    metrics = {}
    glyphTable = fb.font["glyf"]
    for gn, advanceWidth in advanceWidths.items():
        metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
    fb.setupHorizontalMetrics(metrics)

    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)

    axes = [
        ('LEFT', 0, 0, 100, "Left"),
        ('RGHT', 0, 0, 100, "Right"),
        ('UPPP', 0, 0, 100, "Up"),
        ('DOWN', 0, 0, 100, "Down"),
    ]
    instances = [
        dict(location=dict(LEFT=0, RGHT=0, UPPP=0, DOWN=0), stylename="TotallyNormal"),
        dict(location=dict(LEFT=0, RGHT=100, UPPP=100, DOWN=0), stylename="Right Up"),
    ]
    fb.setupFvar(axes, instances)
    variations = {}
    # Four (x, y) pairs and four phantom points:
    leftDeltas = [(-200, 0), (-200, 0), (0, 0), (0, 0), None, None, None, None]
    rightDeltas = [(0, 0), (0, 0), (200, 0), (200, 0), None, None, None, None]
    upDeltas = [(0, 0), (0, 200), (0, 200), (0, 0), None, None, None, None]
    downDeltas = [(0, -200), (0, 0), (0, 0), (0, -200), None, None, None, None]
    variations['a'] = [
        TupleVariation(dict(RGHT=(0, 1, 1)), rightDeltas),
        TupleVariation(dict(LEFT=(0, 1, 1)), leftDeltas),
        TupleVariation(dict(UPPP=(0, 1, 1)), upDeltas),
        TupleVariation(dict(DOWN=(0, 1, 1)), downDeltas),
    ]
    fb.setupGvar(variations)

    fb.setupOS2()
    fb.setupPost()
    fb.setupDummyDSIG()

    fb.save(outPath)

    _verifyOutput(outPath)
Пример #3
0
    def test_out_of_range_transform_decomposed(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (3, 0, 0, 2, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, 1, -1, 2))
        pen.addComponent(componentName, (2, 0, 0, -3, 0, 0))
        compositeGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 2))
        pen.lineTo((3, 0))
        pen.closePath()
        pen.moveTo((-1, 2))
        pen.lineTo((-1, 3))
        pen.lineTo((0, 2))
        pen.closePath()
        pen.moveTo((0, 0))
        pen.lineTo((0, -3))
        pen.lineTo((2, 0))
        pen.closePath()
        expectedGlyph = pen.glyph()

        assert expectedGlyph == compositeGlyph
Пример #4
0
    def test_clamp_to_almost_2_component_transform(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (1.99999, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 2, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 2, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, 2, 0, 0))
        pen.addComponent(componentName, (-2, 0, 0, -2, 0, 0))
        compositeGlyph = pen.glyph()

        almost2 = MAX_F2DOT14  # 0b1.11111111111111
        pen.addComponent(componentName, (almost2, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, almost2, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, almost2, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, almost2, 0, 0))
        pen.addComponent(componentName, (-2, 0, 0, -2, 0, 0))
        expectedGlyph = pen.glyph()

        assert expectedGlyph == compositeGlyph
Пример #5
0
    def test_out_of_range_transform_decomposed(self):
        componentName = 'a'
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (3, 0, 0, 2, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, 1, -1, 2))
        pen.addComponent(componentName, (2, 0, 0, -3, 0, 0))
        compositeGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 2))
        pen.lineTo((3, 0))
        pen.closePath()
        pen.moveTo((-1, 2))
        pen.lineTo((-1, 3))
        pen.lineTo((0, 2))
        pen.closePath()
        pen.moveTo((0, 0))
        pen.lineTo((0, -3))
        pen.lineTo((2, 0))
        pen.closePath()
        expectedGlyph = pen.glyph()

        self.assertEqual(expectedGlyph, compositeGlyph)
Пример #6
0
    def test_scaled_component_bounds(self):
        glyphSet = {}

        pen = TTGlyphPen(glyphSet)
        pen.moveTo((-231, 939))
        pen.lineTo((-55, 939))
        pen.lineTo((-55, 745))
        pen.lineTo((-231, 745))
        pen.closePath()
        glyphSet["gravecomb"] = pen.glyph()

        pen = TTGlyphPen(glyphSet)
        pen.moveTo((-278, 939))
        pen.lineTo((8, 939))
        pen.lineTo((8, 745))
        pen.lineTo((-278, 745))
        pen.closePath()
        glyphSet["circumflexcomb"] = pen.glyph()

        pen = TTGlyphPen(glyphSet)
        pen.addComponent("circumflexcomb", (1, 0, 0, 1, 0, 0))
        pen.addComponent("gravecomb", (0.9, 0, 0, 0.9, 198, 180))
        glyphSet["uni0302_uni0300"] = uni0302_uni0300 = pen.glyph()

        uni0302_uni0300.recalcBounds(glyphSet)
        self.assertGlyphBoundsEqual(uni0302_uni0300, (-278, 745, 148, 1025))
Пример #7
0
    def test_clamp_to_almost_2_component_transform(self):
        componentName = 'a'
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (1.99999, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 2, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 2, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, 2, 0, 0))
        pen.addComponent(componentName, (-2, 0, 0, -2, 0, 0))
        compositeGlyph = pen.glyph()

        almost2 = MAX_F2DOT14  # 0b1.11111111111111
        pen.addComponent(componentName, (almost2, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, almost2, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, almost2, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, almost2, 0, 0))
        pen.addComponent(componentName, (-2, 0, 0, -2, 0, 0))
        expectedGlyph = pen.glyph()

        self.assertEqual(expectedGlyph, compositeGlyph)
Пример #8
0
    def test_glyph_decomposes(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        pen.addComponent(componentName, (1, 0, 0, 1, 2, 0))
        pen.addComponent("missing", (1, 0, 0, 1, 0, 0))  # skipped
        compositeGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        pen.moveTo((2, 0))
        pen.lineTo((2, 1))
        pen.lineTo((3, 0))
        pen.closePath()
        plainGlyph = pen.glyph()

        assert plainGlyph == compositeGlyph
Пример #9
0
    def test_glyph_decomposes(self):
        componentName = 'a'
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        pen.addComponent(componentName, (1, 0, 0, 1, 2, 0))
        compositeGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        pen.moveTo((2, 0))
        pen.lineTo((2, 1))
        pen.lineTo((3, 0))
        pen.closePath()
        plainGlyph = pen.glyph()

        plainGlyph.program = compositeGlyph.program
        self.assertEqual(plainGlyph, compositeGlyph)
Пример #10
0
 def test_recursiveComponent(self):
     glyphSet = {}
     pen_dummy = TTGlyphPen(glyphSet)
     glyph_dummy = pen_dummy.glyph()
     glyphSet["A"] = glyph_dummy
     glyphSet["B"] = glyph_dummy
     pen_A = TTGlyphPen(glyphSet)
     pen_A.addComponent("B", (1, 0, 0, 1, 0, 0))
     pen_B = TTGlyphPen(glyphSet)
     pen_B.addComponent("A", (1, 0, 0, 1, 0, 0))
     glyph_A = pen_A.glyph()
     glyph_B = pen_B.glyph()
     glyphSet["A"] = glyph_A
     glyphSet["B"] = glyph_B
     with self.assertRaisesRegex(TTLibError, "glyph '.' contains a recursive component reference"):
         glyph_A.getCoordinates(glyphSet)
Пример #11
0
    def test_trim_remove_hinting_composite_glyph(self):
        glyphSet = {"dummy": TTGlyphPen(None).glyph()}

        pen = TTGlyphPen(glyphSet)
        pen.addComponent("dummy", (1, 0, 0, 1, 0, 0))
        composite = pen.glyph()
        p = ttProgram.Program()
        p.fromAssembly(['SVTCA[0]'])
        composite.program = p
        glyphSet["composite"] = composite

        glyfTable = newTable("glyf")
        glyfTable.glyphs = glyphSet
        glyfTable.glyphOrder = sorted(glyphSet)

        composite.compact(glyfTable)

        self.assertTrue(hasattr(composite, "data"))

        # remove hinting from the compacted composite glyph, without expanding it
        composite.trim(remove_hinting=True)

        # check that, after expanding the glyph, we have no instructions
        composite.expand(glyfTable)
        self.assertFalse(hasattr(composite, "program"))

        # now remove hinting from expanded composite glyph
        composite.program = p
        composite.trim(remove_hinting=True)

        # check we have no instructions
        self.assertFalse(hasattr(composite, "program"))

        composite.compact(glyfTable)
Пример #12
0
    def test_trim_remove_hinting_composite_glyph(self):
        glyphSet = {"dummy": TTGlyphPen(None).glyph()}

        pen = TTGlyphPen(glyphSet)
        pen.addComponent("dummy", (1, 0, 0, 1, 0, 0))
        composite = pen.glyph()
        p = ttProgram.Program()
        p.fromAssembly(['SVTCA[0]'])
        composite.program = p
        glyphSet["composite"] = composite

        glyfTable = newTable("glyf")
        glyfTable.glyphs = glyphSet
        glyfTable.glyphOrder = sorted(glyphSet)

        composite.compact(glyfTable)

        self.assertTrue(hasattr(composite, "data"))

        # remove hinting from the compacted composite glyph, without expanding it
        composite.trim(remove_hinting=True)

        # check that, after expanding the glyph, we have no instructions
        composite.expand(glyfTable)
        self.assertFalse(hasattr(composite, "program"))

        # now remove hinting from expanded composite glyph
        composite.program = p
        composite.trim(remove_hinting=True)

        # check we have no instructions
        self.assertFalse(hasattr(composite, "program"))

        composite.compact(glyfTable)
Пример #13
0
    def setupTable_glyf(self):
        """Make the glyf table."""

        allGlyphs = self.allGlyphs
        if self.convertCubics:
            from cu2qu.pens import Cu2QuPen
            allGlyphs = {}
            for name, glyph in self.allGlyphs.items():
                if isinstance(glyph, StubGlyph):
                    allGlyphs[name] = glyph
                    continue
                newGlyph = glyph.__class__()
                glyph.draw(
                    Cu2QuPen(newGlyph.getPen(),
                             self.cubicConversionError,
                             reverse_direction=True))
                # the width is needed for autoUseMyMetrics method below
                newGlyph.width = glyph.width
                allGlyphs[name] = newGlyph

        self.otf["loca"] = newTable("loca")
        self.otf["glyf"] = glyf = newTable("glyf")
        glyf.glyphs = {}
        glyf.glyphOrder = self.glyphOrder

        for name in self.glyphOrder:
            glyph = allGlyphs[name]
            pen = TTGlyphPen(allGlyphs)
            glyph.draw(pen)
            ttGlyph = pen.glyph()
            if ttGlyph.isComposite() and self.autoUseMyMetrics:
                self.autoUseMyMetrics(ttGlyph, glyph.width, allGlyphs)
            glyf[name] = ttGlyph
Пример #14
0
    def setupTable_glyf(self):
        """Make the glyf table."""

        allGlyphs = self.allGlyphs
        if self.convertCubics:
            from cu2qu.pens import Cu2QuPen
            allGlyphs = {}
            for name, glyph in self.allGlyphs.items():
                if isinstance(glyph, StubGlyph):
                    allGlyphs[name] = glyph
                    continue
                newGlyph = glyph.__class__()
                glyph.draw(Cu2QuPen(
                    newGlyph.getPen(), self.cubicConversionError,
                    reverse_direction=True))
                allGlyphs[name] = newGlyph

        self.otf["loca"] = newTable("loca")
        self.otf["glyf"] = glyf = newTable("glyf")
        glyf.glyphs = {}
        glyf.glyphOrder = self.glyphOrder

        for name in self.glyphOrder:
            pen = TTGlyphPen(allGlyphs)
            allGlyphs[name].draw(pen)
            glyf[name] = pen.glyph()
Пример #15
0
    def test_endPath_sameAsClosePath(self):
        pen = TTGlyphPen(None)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        closePathGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.endPath()
        endPathGlyph = pen.glyph()

        assert closePathGlyph == endPathGlyph
Пример #16
0
def empty_svg_font():
    glyph_order = [".notdef"] + list(ascii_letters)

    pen = TTGlyphPen(glyphSet=None)
    pen.moveTo((0, 0))
    pen.lineTo((0, 500))
    pen.lineTo((500, 500))
    pen.lineTo((500, 0))
    pen.closePath()
    glyph = pen.glyph()
    glyphs = {g: glyph for g in glyph_order}

    fb = FontBuilder(unitsPerEm=1024, isTTF=True)
    fb.setupGlyphOrder(glyph_order)
    fb.setupCharacterMap({ord(c): c for c in ascii_letters})
    fb.setupGlyf(glyphs)
    fb.setupHorizontalMetrics({g: (500, 0) for g in glyph_order})
    fb.setupHorizontalHeader()
    fb.setupOS2()
    fb.setupPost()
    fb.setupNameTable({"familyName": "TestSVG", "styleName": "Regular"})

    svg_table = newTable("SVG ")
    svg_table.docList = []
    fb.font["SVG "] = svg_table

    return fb.font
Пример #17
0
def test_build_ttf(tmpdir):
    outPath = os.path.join(str(tmpdir), "test.ttf")

    fb, advanceWidths, nameStrings = _setupFontBuilder(True)

    pen = TTGlyphPen(None)
    drawTestGlyph(pen)
    glyph = pen.glyph()
    glyphs = {".notdef": glyph, "A": glyph, "a": glyph, ".null": glyph}
    fb.setupGlyf(glyphs)
    metrics = {}
    glyphTable = fb.font["glyf"]
    for gn, advanceWidth in advanceWidths.items():
        metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
    fb.setupHorizontalMetrics(metrics)

    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)
    fb.setupOS2()
    fb.setupPost()
    fb.setupDummyDSIG()

    fb.save(outPath)

    f = TTFont(outPath)
    f.saveXML(outPath + ".ttx")
    with open(outPath + ".ttx") as f:
        testData = strip_VariableItems(f.read())
    refData = strip_VariableItems(getTestData("test.ttf.ttx"))
    assert refData == testData
Пример #18
0
def test_build_ttf(tmpdir):
    outPath = os.path.join(str(tmpdir), "test.ttf")

    fb, advanceWidths, nameStrings = _setupFontBuilder(True)

    pen = TTGlyphPen(None)
    drawTestGlyph(pen)
    glyph = pen.glyph()
    glyphs = {".notdef": glyph, "A": glyph, "a": glyph, ".null": glyph}
    fb.setupGlyf(glyphs)
    metrics = {}
    glyphTable = fb.font["glyf"]
    for gn, advanceWidth in advanceWidths.items():
        metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
    fb.setupHorizontalMetrics(metrics)

    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)
    fb.setupOS2()
    fb.setupPost()
    fb.setupDummyDSIG()

    fb.save(outPath)

    _verifyOutput(outPath)
Пример #19
0
    def test_endPath_sameAsClosePath(self):
        pen = TTGlyphPen(None)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        closePathGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.endPath()
        endPathGlyph = pen.glyph()

        self.assertEqual(closePathGlyph, endPathGlyph)
Пример #20
0
def test_build_ttf(tmpdir):
    outPath = os.path.join(str(tmpdir), "test.ttf")

    fb, advanceWidths, nameStrings = _setupFontBuilder(True)

    pen = TTGlyphPen(None)
    drawTestGlyph(pen)
    glyph = pen.glyph()
    glyphs = {".notdef": glyph, "A": glyph, "a": glyph, ".null": glyph}
    fb.setupGlyf(glyphs)
    metrics = {}
    glyphTable = fb.font["glyf"]
    for gn, advanceWidth in advanceWidths.items():
        metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
    fb.setupHorizontalMetrics(metrics)

    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)
    fb.setupOS2()
    fb.setupPost()
    fb.setupDummyDSIG()

    fb.save(outPath)

    f = TTFont(outPath)
    f.saveXML(outPath + ".ttx")
    with open(outPath + ".ttx") as f:
        testData = strip_VariableItems(f.read())
    refData = strip_VariableItems(getTestData("test.ttf.ttx"))
    assert refData == testData
Пример #21
0
    def setupTable_glyf(self):
        """Make the glyf table."""

        allGlyphs = self.allGlyphs
        if self.convertCubics:
            from cu2qu.pens import Cu2QuPen
            allGlyphs = {}
            for name, glyph in self.allGlyphs.items():
                if isinstance(glyph, StubGlyph):
                    allGlyphs[name] = glyph
                    continue
                newGlyph = glyph.__class__()
                glyph.draw(
                    Cu2QuPen(newGlyph.getPen(),
                             self.cubicConversionError,
                             reverse_direction=True))
                allGlyphs[name] = newGlyph

        self.otf["loca"] = newTable("loca")
        self.otf["glyf"] = glyf = newTable("glyf")
        glyf.glyphs = {}
        glyf.glyphOrder = self.glyphOrder

        for name in self.glyphOrder:
            pen = TTGlyphPen(allGlyphs)
            allGlyphs[name].draw(pen)
            glyf[name] = pen.glyph()
Пример #22
0
def test_build_ttf(tmpdir):
    outPath = os.path.join(str(tmpdir), "test.ttf")

    fb, advanceWidths, nameStrings = _setupFontBuilder(True)

    pen = TTGlyphPen(None)
    drawTestGlyph(pen)
    glyph = pen.glyph()
    glyphs = {".notdef": glyph, "A": glyph, "a": glyph, ".null": glyph}
    fb.setupGlyf(glyphs)
    metrics = {}
    glyphTable = fb.font["glyf"]
    for gn, advanceWidth in advanceWidths.items():
        metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
    fb.setupHorizontalMetrics(metrics)

    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)
    fb.setupOS2()
    fb.setupPost()
    fb.setupDummyDSIG()

    fb.save(outPath)

    _verifyOutput(outPath)
Пример #23
0
 def test_recursiveComponent(self):
     glyphSet = {}
     pen_dummy = TTGlyphPen(glyphSet)
     glyph_dummy = pen_dummy.glyph()
     glyphSet["A"] = glyph_dummy
     glyphSet["B"] = glyph_dummy
     pen_A = TTGlyphPen(glyphSet)
     pen_A.addComponent("B", (1, 0, 0, 1, 0, 0))
     pen_B = TTGlyphPen(glyphSet)
     pen_B.addComponent("A", (1, 0, 0, 1, 0, 0))
     glyph_A = pen_A.glyph()
     glyph_B = pen_B.glyph()
     glyphSet["A"] = glyph_A
     glyphSet["B"] = glyph_B
     with self.assertRaisesRegex(TTLibError, "glyph '.' contains a recursive component reference"):
         glyph_A.getCoordinates(glyphSet)
Пример #24
0
    def test_endPath_sameAsClosePath(self):
        pen = TTGlyphPen(None)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        closePathGlyph = pen.glyph()

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.endPath()
        endPathGlyph = pen.glyph()

        endPathGlyph.program = closePathGlyph.program
        self.assertEqual(closePathGlyph, endPathGlyph)
Пример #25
0
def ttfGlyphFromSkPath(path: pathops.Path) -> _g_l_y_f.Glyph:
    # Skia paths have no 'components', no need for glyphSet
    ttPen = TTGlyphPen(glyphSet=None)
    path.draw(ttPen)
    glyph = ttPen.glyph()
    assert not glyph.isComposite()
    # compute glyph.xMin (glyfTable parameter unused for non composites)
    glyph.recalcBounds(glyfTable=None)
    return glyph
Пример #26
0
def glyphs_to_quadratic(glyphs, max_err, **kwargs):
    quadGlyphs = {}
    for gname in glyphs.keys():
        glyph = glyphs[gname]
        ttPen = TTGlyphPen(glyphs)
        cu2quPen = Cu2QuPen(ttPen, max_err, **kwargs)
        glyph.draw(cu2quPen)
        quadGlyphs[gname] = ttPen.glyph()
    return quadGlyphs
def makeCollectionHmtxTransform2():
    fonts = [getTTFont(sfntTTFSourcePath), getTTFont(sfntTTFSourcePath)]
    for i, font in enumerate(fonts):
        glyf = font["glyf"]
        hmtx = font["hmtx"]
        maxp = font["maxp"]
        for name in glyf.glyphs:
            glyph = glyf.glyphs[name]
            glyph.expand(glyf)
            if hasattr(glyph, "xMin"):
                metrics = hmtx.metrics[name]
                if i == 0:
                    # Move the glyph so that xMin is 0
                    pen = TTGlyphPen(None)
                    glyph.draw(pen, glyf, -glyph.xMin)
                    glyph = pen.glyph()
                    glyph.recalcBounds(glyf)
                    assert glyph.xMin == 0
                    glyf.glyphs[name] = glyph
                hmtx.metrics[name] = (metrics[0], 0)

        # Build a unique glyph for each font, but with the same advance and LSB
        name = "box"
        pen = TTGlyphPen(None)
        pen.moveTo([0, 0])
        pen.lineTo([0, 1000])
        if i > 0:
            pen.lineTo([0, 2000])
            pen.lineTo([1000, 2000])
        pen.lineTo([1000, 1000])
        pen.lineTo([1000, 0])
        pen.closePath()
        glyph = pen.glyph()
        glyph.recalcBounds(glyf)
        glyf.glyphs[name] = glyph
        hmtx.metrics[name] = (glyph.xMax, glyph.xMin)
        glyf.glyphOrder.append(name)
        maxp.recalc(font)
        data = hmtx.compile(font)
        hmtx.decompile(data, font)

    data = getSFNTCollectionData(fonts, shared=["hmtx"])

    return data
Пример #28
0
    def test_no_handle_overflowing_transform(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPen(glyphSet, handleOverflowingTransforms=False)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        baseGlyph = pen.glyph()
        glyphSet[componentName] = _TestGlyph(baseGlyph)

        pen.addComponent(componentName, (3, 0, 0, 1, 0, 0))
        compositeGlyph = pen.glyph()

        assert compositeGlyph.components[0].transform == ((3, 0), (0, 1))

        with pytest.raises(struct.error):
            compositeGlyph.compile({"a": baseGlyph})
Пример #29
0
def skia_path_to_ttfont_glyph(skia_path: pathops.Path) -> _g_l_y_f.Glyph:
    """
    Converts a pathops.Path object to a fontTools.ttLib._g_l_y_f.Glyph
    object
    """
    tt_pen = TTGlyphPen(glyphSet=None)
    skia_path.draw(tt_pen)
    glyph = tt_pen.glyph()
    glyph.recalcBounds(glyfTable=None)
    return glyph
Пример #30
0
    def test_within_range_component_transform(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (1.5, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, -1.5, 0, 0))
        compositeGlyph = pen.glyph()

        pen.addComponent(componentName, (1.5, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, -1.5, 0, 0))
        expectedGlyph = pen.glyph()

        assert expectedGlyph == compositeGlyph
Пример #31
0
def glyphs_to_quadratic(
        glyphs, max_err=MAX_ERR, reverse_direction=REVERSE_DIRECTION):
    quadGlyphs = {}
    for gname in glyphs.keys():
        glyph = glyphs[gname]
        ttPen = TTGlyphPen(glyphs)
        cu2quPen = Cu2QuPen(ttPen, max_err,
                            reverse_direction=reverse_direction)
        glyph.draw(cu2quPen)
        quadGlyphs[gname] = ttPen.glyph()
    return quadGlyphs
Пример #32
0
def glyphs_to_quadratic(
        glyphs, max_err=MAX_ERR, reverse_direction=REVERSE_DIRECTION):
    quadGlyphs = {}
    for gname in glyphs.keys():
        glyph = glyphs[gname]
        ttPen = TTGlyphPen(glyphs)
        cu2quPen = Cu2QuPen(ttPen, max_err,
                            reverse_direction=reverse_direction)
        glyph.draw(cu2quPen)
        quadGlyphs[gname] = ttPen.glyph()
    return quadGlyphs
Пример #33
0
    def test_within_range_component_transform(self):
        componentName = 'a'
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (1.5, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, -1.5, 0, 0))
        compositeGlyph = pen.glyph()

        pen.addComponent(componentName, (1.5, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, -1.5, 0, 0))
        expectedGlyph = pen.glyph()

        self.assertEqual(expectedGlyph, compositeGlyph)
Пример #34
0
    def test_no_handle_overflowing_transform(self):
        componentName = 'a'
        glyphSet = {}
        pen = TTGlyphPen(glyphSet, handleOverflowingTransforms=False)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((1, 0))
        pen.closePath()
        baseGlyph = pen.glyph()
        glyphSet[componentName] = _TestGlyph(baseGlyph)

        pen.addComponent(componentName, (3, 0, 0, 1, 0, 0))
        compositeGlyph = pen.glyph()

        self.assertEqual(compositeGlyph.components[0].transform,
                         ((3, 0), (0, 1)))

        with self.assertRaises(struct.error):
            compositeGlyph.compile({'a': baseGlyph})
def makeGlyfBBox1(calcBBoxes=True, composite=False):
    font = getTTFont(sfntTTFSourcePath, recalcBBoxes=calcBBoxes)
    glyf = font["glyf"]
    hmtx = font["hmtx"]
    for name in ("bbox1", "bbox2"):
        pen = TTGlyphPen(None)
        if name == "bbox1":
            pen.moveTo((0, 0))
            pen.lineTo((0, 1000))
            pen.lineTo((1000, 1000))
            pen.lineTo((1000, 0))
            pen.closePath()
        else:
            pen.moveTo((0, 0))
            pen.qCurveTo((500, 750), (600, 500), (500, 250), (0, 0))
            pen.closePath()
        glyph = pen.glyph()
        if not calcBBoxes:
            glyph.recalcBounds(glyf)
            glyph.xMax -= 100
        glyf.glyphs[name] = glyph
        hmtx.metrics[name] = (0, 0)
        glyf.glyphOrder.append(name)

    if composite:
        name = "bbox3"
        pen = TTGlyphPen(glyf.glyphOrder)
        pen.addComponent("bbox1", [1, 0, 0, 1, 0, 0])
        pen.addComponent("bbox2", [1, 0, 0, 1, 1000, 0])
        glyph = pen.glyph()
        glyph.recalcBounds(glyf)
        glyf.glyphs[name] = glyph
        hmtx.metrics[name] = (0, 0)
        glyf.glyphOrder.append(name)

    tableData = getSFNTData(font)[0]
    font.close()
    del font
    header, directory, tableData = defaultSFNTTestData(tableData=tableData, flavor="TTF")
    data = packSFNT(header, directory, tableData, flavor="TTF")
    return data
Пример #36
0
    def setupTable_glyf(self):
        """Make the glyf table."""

        self.otf["loca"] = newTable("loca")
        self.otf["glyf"] = glyf = newTable("glyf")
        glyf.glyphs = {}
        glyf.glyphOrder = self.glyphOrder

        for glyph in self.ufo:
            pen = TTGlyphPen(self.ufo)
            glyph.draw(pen)
            glyf[glyph.name] = pen.glyph()
Пример #37
0
    def test_round_float_coordinates_and_component_offsets(self):
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)

        pen.moveTo((0, 0))
        pen.lineTo((0, 1))
        pen.lineTo((367.6, 0))
        pen.closePath()
        simpleGlyph = pen.glyph()

        simpleGlyph.recalcBounds(glyphSet)
        self.assertGlyphBoundsEqual(simpleGlyph, (0, 0, 368, 1))

        componentName = "a"
        glyphSet[componentName] = simpleGlyph

        pen.addComponent(componentName, (1, 0, 0, 1, -86.4, 0))
        compositeGlyph = pen.glyph()

        compositeGlyph.recalcBounds(glyphSet)
        self.assertGlyphBoundsEqual(compositeGlyph, (-86, 0, 282, 1))
Пример #38
0
    def setupTable_glyf(self):
        """Make the glyf table."""

        self.otf["loca"] = newTable("loca")
        self.otf["glyf"] = glyf = newTable("glyf")
        glyf.glyphs = {}
        glyf.glyphOrder = self.glyphOrder

        for name in self.glyphOrder:
            pen = TTGlyphPen(self.allGlyphs)
            self.allGlyphs[name].draw(pen)
            glyf[name] = pen.glyph()
Пример #39
0
 def test_getCompositeMaxpValues(self):
     # https://github.com/fonttools/fonttools/issues/2044
     glyphSet = {}
     pen = TTGlyphPen(glyphSet)  # empty non-composite glyph
     glyphSet["fraction"] = pen.glyph()
     glyphSet["zero.numr"] = pen.glyph()
     pen = TTGlyphPen(glyphSet)
     pen.addComponent("zero.numr", (1, 0, 0, 1, 0, 0))
     glyphSet["zero.dnom"] = pen.glyph()
     pen = TTGlyphPen(glyphSet)
     pen.addComponent("zero.numr", (1, 0, 0, 1, 0, 0))
     pen.addComponent("fraction", (1, 0, 0, 1, 0, 0))
     pen.addComponent("zero.dnom", (1, 0, 0, 1, 0, 0))
     glyphSet["percent"] = pen.glyph()
     pen = TTGlyphPen(glyphSet)
     pen.addComponent("zero.numr", (1, 0, 0, 1, 0, 0))
     pen.addComponent("fraction", (1, 0, 0, 1, 0, 0))
     pen.addComponent("zero.dnom", (1, 0, 0, 1, 0, 0))
     pen.addComponent("zero.dnom", (1, 0, 0, 1, 0, 0))
     glyphSet["perthousand"] = pen.glyph()
     assert glyphSet["zero.dnom"].getCompositeMaxpValues(glyphSet)[2] == 1
     assert glyphSet["percent"].getCompositeMaxpValues(glyphSet)[2] == 2
     assert glyphSet["perthousand"].getCompositeMaxpValues(glyphSet)[2] == 2
Пример #40
0
    def __init__(self,
                 path=None,
                 lazy=False,
                 size=1500,
                 ft_load_glyph_flags=FTHintMode.UNHINTED):
        self.path = path
        self.ttfont = TTFont(self.path)

        has_outlines = self.ttfont.has_key("glyf") or self.ttfont.has_key(
            "CFF ")
        if not has_outlines:
            # Create faux empty glyf table with empty glyphs to make
            # it a valid font, e.g. for old-style CBDT/CBLC fonts
            logger.warning(
                "No outlines present, treating {} as bitmap font".format(
                    self.path))
            self.ttfont["glyf"] = newTable("glyf")
            self.ttfont["glyf"].glyphs = {}
            pen = TTGlyphPen({})
            for name in self.ttfont.getGlyphOrder():
                self.ttfont["glyf"].glyphs[name] = pen.glyph()

        self._src_ttfont = TTFont(self.path)
        self.glyphset = None
        self.recalc_glyphset()
        self.axis_order = None
        self.instance_coordinates = self._get_dflt_instance_coordinates()
        self.instances_coordinates = self._get_instances_coordinates()
        self.glyphs = self.marks = self.mkmks = self.kerns = \
            self.glyph_metrics = self.names = self.attribs = None

        self.ftfont = freetype.Face(self.path)
        self.ftslot = self.ftfont.glyph
        self.ft_load_glyph_flags = ft_load_glyph_flags

        self.size = size
        if self.ftfont.is_scalable:
            self.ftfont.set_char_size(self.size)

        with open(self.path, 'rb') as fontfile:
            self._fontdata = fontfile.read()
        self.hbface = hb.Face.create(self._fontdata)
        self.hbfont = hb.Font.create(self.hbface)

        self.hbfont.scale = (self.size, self.size)

        if not lazy:
            self.recalc_tables()
Пример #41
0
 def process_glyf(self) -> None:
     """
     Processes glyf table
     """
     if self.ttf_components:
         glyf = self.font["glyf"]
         gs = self.font.getGlyphSet()
         for glyph_name in self.font.glyphOrder:
             if glyph_name in self.keep_g_names:
                 continue
             pen = TTGlyphPen(gs)
             pen.addComponent(self.replacer, (1, 0, 0, 1, 0, 0))
             glyf[glyph_name] = pen.glyph()
     else:
         self._process_base(self.font["glyf"])
     return None
Пример #42
0
def glyphs_to_quadratic(glyphs,
                        max_err=MAX_ERR,
                        reverse_direction=REVERSE_DIRECTION):
    try:
        from cu2qu.pens import Cu2QuPen
        from fontTools.pens.ttGlyphPen import TTGlyphPen
    except ImportError:
        raise ValueError("cannot convert glyphs due to missing libs")
    quadGlyphs = {}
    for gname in glyphs.keys():
        glyph = glyphs[gname]
        ttPen = TTGlyphPen(glyphs)
        cu2quPen = Cu2QuPen(ttPen,
                            max_err,
                            reverse_direction=reverse_direction)
        glyph.draw(cu2quPen)
        quadGlyphs[gname] = ttPen.glyph()
    return quadGlyphs
Пример #43
0
 def draw(self, ppp: float):
     pen = TTGlyphPen(None)
     for y, row in enumerate(reversed(self.bits)):
         for x, col in enumerate(row):
             if col:
                 pen.moveTo(
                     ((x + self.bbx.x) * ppp, (y + self.bbx.y) * ppp))
                 pen.lineTo(
                     ((x + self.bbx.x + 1) * ppp, (y + self.bbx.y) * ppp))
                 pen.lineTo((
                     (x + self.bbx.x + 1) * ppp,
                     (y + self.bbx.y + 1) * ppp,
                 ))
                 pen.lineTo(
                     ((x + self.bbx.x) * ppp, (y + self.bbx.y + 1) * ppp))
                 pen.lineTo(
                     ((x + self.bbx.x) * ppp, (y + self.bbx.y) * ppp))
                 pen.closePath()
     return pen.glyph()
Пример #44
0
def decomposeAndRemoveOverlap(font, glyphName):

    glyfTable = font["glyf"]
    glyphSet = font.getGlyphSet()

    # record TTGlyph outlines without components
    dcPen = DecomposingRecordingPen(glyphSet)
    glyphSet[glyphName].draw(dcPen)

    # replay recording onto a skia-pathops Path
    path = pathops.Path()
    pathPen = path.getPen()
    dcPen.replay(pathPen)

    # remove overlaps
    path.simplify()

    # create new TTGlyph from Path
    ttPen = TTGlyphPen(None)
    path.draw(ttPen)
    glyfTable[glyphName] = ttPen.glyph()
Пример #45
0
def test_unicodeVariationSequences(tmpdir):
    familyName = "UVSTestFont"
    styleName = "Regular"
    nameStrings = dict(familyName=familyName, styleName=styleName)
    nameStrings['psName'] = familyName + "-" + styleName
    glyphOrder = [".notdef", "space", "zero", "zero.slash"]
    cmap = {ord(" "): "space", ord("0"): "zero"}
    uvs = [
        (0x0030, 0xFE00, "zero.slash"),
        (0x0030, 0xFE01, None),  # not an official sequence, just testing
    ]
    metrics = {gn: (600, 0) for gn in glyphOrder}
    pen = TTGlyphPen(None)
    glyph = pen.glyph()  # empty placeholder
    glyphs = {gn: glyph for gn in glyphOrder}

    fb = FontBuilder(1024, isTTF=True)
    fb.setupGlyphOrder(glyphOrder)
    fb.setupCharacterMap(cmap, uvs)
    fb.setupGlyf(glyphs)
    fb.setupHorizontalMetrics(metrics)
    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)
    fb.setupOS2()
    fb.setupPost()

    outPath = os.path.join(str(tmpdir), "test_uvs.ttf")
    fb.save(outPath)
    _verifyOutput(outPath, tables=["cmap"])

    uvs = [
        (0x0030, 0xFE00, "zero.slash"),
        (
            0x0030, 0xFE01, "zero"
        ),  # should result in the exact same subtable data, due to cmap[0x0030] == "zero"
    ]
    fb.setupCharacterMap(cmap, uvs)
    fb.save(outPath)
    _verifyOutput(outPath, tables=["cmap"])
Пример #46
0
    def runEndToEnd(self, filename):
        font = ttLib.TTFont()
        ttx_path = os.path.join(
            os.path.abspath(os.path.dirname(os.path.realpath(__file__))),
            '..', 'ttLib', 'data', filename)
        font.importXML(ttx_path)

        glyphSet = font.getGlyphSet()
        glyfTable = font['glyf']
        pen = TTGlyphPen(font.getGlyphSet())

        for name in font.getGlyphOrder():
            oldGlyph = glyphSet[name]
            oldGlyph.draw(pen)
            oldGlyph = oldGlyph._glyph
            newGlyph = pen.glyph()

            if hasattr(oldGlyph, 'program'):
                newGlyph.program = oldGlyph.program

            self.assertEqual(
                oldGlyph.compile(glyfTable), newGlyph.compile(glyfTable))
Пример #47
0
def test_unicodeVariationSequences(tmpdir):
    familyName = "UVSTestFont"
    styleName = "Regular"
    nameStrings = dict(familyName=familyName, styleName=styleName)
    nameStrings['psName'] = familyName + "-" + styleName
    glyphOrder = [".notdef", "space", "zero", "zero.slash"]
    cmap = {ord(" "): "space", ord("0"): "zero"}
    uvs = [
        (0x0030, 0xFE00, "zero.slash"),
        (0x0030, 0xFE01, None),  # not an official sequence, just testing
    ]
    metrics = {gn: (600, 0) for gn in glyphOrder}
    pen = TTGlyphPen(None)
    glyph = pen.glyph()  # empty placeholder
    glyphs = {gn: glyph for gn in glyphOrder}

    fb = FontBuilder(1024, isTTF=True)
    fb.setupGlyphOrder(glyphOrder)
    fb.setupCharacterMap(cmap, uvs)
    fb.setupGlyf(glyphs)
    fb.setupHorizontalMetrics(metrics)
    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)
    fb.setupOS2()
    fb.setupPost()

    outPath = os.path.join(str(tmpdir), "test_uvs.ttf")
    fb.save(outPath)
    _verifyOutput(outPath, tables=["cmap"])

    uvs = [
        (0x0030, 0xFE00, "zero.slash"),
        (0x0030, 0xFE01, "zero"),  # should result in the exact same subtable data, due to cmap[0x0030] == "zero"
    ]
    fb.setupCharacterMap(cmap, uvs)
    fb.save(outPath)
    _verifyOutput(outPath, tables=["cmap"])
Пример #48
0
def test_build_var(tmpdir):
    outPath = os.path.join(str(tmpdir), "test_var.ttf")

    fb = FontBuilder(1024, isTTF=True)
    fb.setupGlyphOrder([".notdef", ".null", "A", "a"])
    fb.setupCharacterMap({65: "A", 97: "a"})

    advanceWidths = {".notdef": 600, "A": 600, "a": 600, ".null": 600}

    familyName = "HelloTestFont"
    styleName = "TotallyNormal"
    nameStrings = dict(familyName=dict(en="HelloTestFont", nl="HalloTestFont"),
                       styleName=dict(en="TotallyNormal", nl="TotaalNormaal"))
    nameStrings['psName'] = familyName + "-" + styleName

    pen = TTGlyphPen(None)
    pen.moveTo((100, 0))
    pen.lineTo((100, 400))
    pen.lineTo((500, 400))
    pen.lineTo((500, 000))
    pen.closePath()

    glyph = pen.glyph()

    pen = TTGlyphPen(None)
    emptyGlyph = pen.glyph()

    glyphs = {".notdef": emptyGlyph, "A": glyph, "a": glyph, ".null": emptyGlyph}
    fb.setupGlyf(glyphs)
    metrics = {}
    glyphTable = fb.font["glyf"]
    for gn, advanceWidth in advanceWidths.items():
        metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
    fb.setupHorizontalMetrics(metrics)

    fb.setupHorizontalHeader(ascent=824, descent=200)
    fb.setupNameTable(nameStrings)

    axes = [
        ('LEFT', 0, 0, 100, "Left"),
        ('RGHT', 0, 0, 100, "Right"),
        ('UPPP', 0, 0, 100, "Up"),
        ('DOWN', 0, 0, 100, "Down"),
    ]
    instances = [
        dict(location=dict(LEFT=0, RGHT=0, UPPP=0, DOWN=0), stylename="TotallyNormal"),
        dict(location=dict(LEFT=0, RGHT=100, UPPP=100, DOWN=0), stylename="Right Up"),
    ]
    fb.setupFvar(axes, instances)
    variations = {}
    # Four (x, y) pairs and four phantom points:
    leftDeltas = [(-200, 0), (-200, 0), (0, 0), (0, 0), None, None, None, None]
    rightDeltas = [(0, 0), (0, 0), (200, 0), (200, 0), None, None, None, None]
    upDeltas = [(0, 0), (0, 200), (0, 200), (0, 0), None, None, None, None]
    downDeltas = [(0, -200), (0, 0), (0, 0), (0, -200), None, None, None, None]
    variations['a'] = [
        TupleVariation(dict(RGHT=(0, 1, 1)), rightDeltas),
        TupleVariation(dict(LEFT=(0, 1, 1)), leftDeltas),
        TupleVariation(dict(UPPP=(0, 1, 1)), upDeltas),
        TupleVariation(dict(DOWN=(0, 1, 1)), downDeltas),
    ]
    fb.setupGvar(variations)

    fb.setupOS2()
    fb.setupPost()
    fb.setupDummyDSIG()

    fb.save(outPath)

    f = TTFont(outPath)
    f.saveXML(outPath + ".ttx")
    with open(outPath + ".ttx") as f:
        testData = strip_VariableItems(f.read())
    refData = strip_VariableItems(getTestData("test_var.ttf.ttx"))
    assert refData == testData
Пример #49
0
def make_font(feature_source, fea_type='fea'):
    """Return font with GSUB compiled from given source.

    Adds a bunch of filler tables so the font can be saved if needed, for
    debugging purposes.
    """

    # copied from fontTools' feaLib/builder_test.
    glyphs = """
        .notdef space slash fraction semicolon period comma ampersand
        quotedblleft quotedblright quoteleft quoteright
        zero one two three four five six seven eight nine
        zero.oldstyle one.oldstyle two.oldstyle three.oldstyle
        four.oldstyle five.oldstyle six.oldstyle seven.oldstyle
        eight.oldstyle nine.oldstyle onequarter onehalf threequarters
        onesuperior twosuperior threesuperior ordfeminine ordmasculine
        A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
        a b c d e f g h i j k l m n o p q r s t u v w x y z
        A.sc B.sc C.sc D.sc E.sc F.sc G.sc H.sc I.sc J.sc K.sc L.sc M.sc
        N.sc O.sc P.sc Q.sc R.sc S.sc T.sc U.sc V.sc W.sc X.sc Y.sc Z.sc
        A.alt1 A.alt2 A.alt3 B.alt1 B.alt2 B.alt3 C.alt1 C.alt2 C.alt3
        a.alt1 a.alt2 a.alt3 a.end b.alt c.mid d.alt d.mid
        e.begin e.mid e.end m.begin n.end s.end z.end
        Eng Eng.alt1 Eng.alt2 Eng.alt3
        A.swash B.swash C.swash D.swash E.swash F.swash G.swash H.swash
        I.swash J.swash K.swash L.swash M.swash N.swash O.swash P.swash
        Q.swash R.swash S.swash T.swash U.swash V.swash W.swash X.swash
        Y.swash Z.swash
        f_l c_h c_k c_s c_t f_f f_f_i f_f_l f_i o_f_f_i s_t f_i.begin
        a_n_d T_h T_h.swash germandbls ydieresis yacute breve
        grave acute dieresis macron circumflex cedilla umlaut ogonek caron
        damma hamza sukun kasratan lam_meem_jeem noon.final noon.initial
        by feature lookup sub table
    """.split()
    font = TTFont()
    font.setGlyphOrder(glyphs)
    glyph_order = font.getGlyphOrder()

    font['cmap'] = cmap = newTable('cmap')
    table = cmap_format_4(4)
    table.platformID = 3
    table.platEncID = 1
    table.language = 0
    table.cmap = {AGL2UV[n]: n for n in glyph_order if n in AGL2UV}
    cmap.tableVersion = 0
    cmap.tables = [table]

    font['glyf'] = glyf = newTable('glyf')
    glyf.glyphs = {}
    glyf.glyphOrder = glyph_order
    for name in glyph_order:
        pen = TTGlyphPen(None)
        glyf[name] = pen.glyph()

    font['head'] = head = newTable('head')
    head.tableVersion = 1.0
    head.fontRevision = 1.0
    head.flags = head.checkSumAdjustment = head.magicNumber =\
        head.created = head.modified = head.macStyle = head.lowestRecPPEM =\
        head.fontDirectionHint = head.indexToLocFormat =\
        head.glyphDataFormat =\
        head.xMin = head.xMax = head.yMin = head.yMax = 0
    head.unitsPerEm = 1000

    font['hhea'] = hhea = newTable('hhea')
    hhea.tableVersion = 0x00010000
    hhea.ascent = hhea.descent = hhea.lineGap =\
        hhea.caretSlopeRise = hhea.caretSlopeRun = hhea.caretOffset =\
        hhea.reserved0 = hhea.reserved1 = hhea.reserved2 = hhea.reserved3 =\
        hhea.metricDataFormat = hhea.advanceWidthMax = hhea.xMaxExtent =\
        hhea.minLeftSideBearing = hhea.minRightSideBearing =\
        hhea.numberOfHMetrics = 0

    font['hmtx'] = hmtx = newTable('hmtx')
    hmtx.metrics = {}
    for name in glyph_order:
        hmtx[name] = (600, 50)

    font['loca'] = newTable('loca')

    font['maxp'] = maxp = newTable('maxp')
    maxp.tableVersion = 0x00005000
    maxp.numGlyphs = 0

    font['post'] = post = newTable('post')
    post.formatType = 2.0
    post.extraNames = []
    post.mapping = {}
    post.glyphOrder = glyph_order
    post.italicAngle = post.underlinePosition = post.underlineThickness =\
        post.isFixedPitch = post.minMemType42 = post.maxMemType42 =\
        post.minMemType1 = post.maxMemType1 = 0

    if fea_type == 'fea':
        addOpenTypeFeaturesFromString(font, feature_source)
    elif fea_type == 'mti':
        font['GSUB'] = mtiLib.build(UnicodeIO(feature_source), font)

    return font
Пример #50
0
 def test_glyph_errorOnUnendedContour(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     with self.assertRaises(AssertionError):
         pen.glyph()