Exemplo n.º 1
0
 def test_closePath_ignoresAnchors(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.closePath()
     self.assertFalse(pen.points)
     self.assertFalse(pen.types)
     self.assertFalse(pen.endPts)
Exemplo n.º 2
0
 def test_closePath_ignoresAnchors(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.closePath()
     self.assertFalse(pen.points)
     self.assertFalse(pen.types)
     self.assertFalse(pen.endPts)
Exemplo n.º 3
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)
Exemplo n.º 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()

        self.assertEqual(expectedGlyph, compositeGlyph)
Exemplo n.º 5
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)
Exemplo n.º 6
0
 def test_remove_extra_move_points(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.lineTo((100, 0))
     pen.qCurveTo((100, 50), (50, 100), (0, 0))
     pen.closePath()
     self.assertEqual(len(pen.points), 4)
     self.assertEqual(pen.points[0], (0, 0))
Exemplo n.º 7
0
 def test_remove_extra_move_points(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.lineTo((100, 0))
     pen.qCurveTo((100, 50), (50, 100), (0, 0))
     pen.closePath()
     self.assertEqual(len(pen.points), 4)
     self.assertEqual(pen.points[0], (0, 0))
Exemplo n.º 8
0
 def test_remove_extra_move_points(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.lineTo((100, 0))
     pen.qCurveTo((100, 50), (50, 100), (0, 0))
     pen.closePath()
     assert len(pen.points) == 4
     assert pen.points[0] == (0, 0)
Exemplo n.º 9
0
 def test_keep_duplicate_end_point(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.lineTo((100, 0))
     pen.qCurveTo((100, 50), (50, 100), (0, 0))
     pen.lineTo((0, 0))  # the duplicate point is not removed
     pen.closePath()
     self.assertEqual(len(pen.points), 5)
     self.assertEqual(pen.points[0], (0, 0))
Exemplo n.º 10
0
 def test_keep_move_point(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.lineTo((100, 0))
     pen.qCurveTo((100, 50), (50, 100), (30, 30))
     # when last and move pts are different, closePath() implies a lineTo
     pen.closePath()
     self.assertEqual(len(pen.points), 5)
     self.assertEqual(pen.points[0], (0, 0))
Exemplo n.º 11
0
 def test_keep_move_point(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.lineTo((100, 0))
     pen.qCurveTo((100, 50), (50, 100), (30, 30))
     # when last and move pts are different, closePath() implies a lineTo
     pen.closePath()
     assert len(pen.points) == 5
     assert pen.points[0] == (0, 0)
Exemplo n.º 12
0
 def test_keep_duplicate_end_point(self):
     pen = TTGlyphPen(None)
     pen.moveTo((0, 0))
     pen.lineTo((100, 0))
     pen.qCurveTo((100, 50), (50, 100), (0, 0))
     pen.lineTo((0, 0))  # the duplicate point is not removed
     pen.closePath()
     assert len(pen.points) == 5
     assert pen.points[0] == (0, 0)
Exemplo n.º 13
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
Exemplo n.º 14
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
Exemplo n.º 15
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)
Exemplo n.º 16
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)
Exemplo n.º 17
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)
Exemplo n.º 18
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
Exemplo n.º 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)
Exemplo n.º 20
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)
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
Exemplo n.º 22
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()
Exemplo n.º 23
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})
Exemplo n.º 24
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)
Exemplo n.º 25
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})
Exemplo n.º 26
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
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
Exemplo n.º 28
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))
Exemplo n.º 29
0
def replaceGlyphRecord(font, fontFile):
    glyfTable = font["glyf"]
    for key in glyfTable.keys():
        glyf = glyfTable[key]
        if fontFile == "TakaoGothic.ttf" and key == "aj247":
            ttPen = TTGlyphPen(glyfTable)
            ttPen.moveTo((512, 1579))
            ttPen.qCurveTo((910, 1579), (910, 821))
            ttPen.qCurveTo((910, 63), (512, 63))
            ttPen.qCurveTo((115, 63), (115, 821))
            ttPen.qCurveTo((115, 1579), None)
            ttPen.closePath()
            ttPen.moveTo((510, 1438))
            ttPen.qCurveTo((283, 1438), (283, 204), (512, 204))
            ttPen.qCurveTo((742, 204), (742, 823))
            ttPen.qCurveTo((742, 1438), None)
            ttPen.closePath()
            glyf = ttPen.glyph()
            glyfTable[key] = glyf

        coordinates = glyf.getCoordinates(glyfTable)
        coordinates[0].translate((0, -137))
        glyf.removeHinting()
    glyfTable.compile(font)
Exemplo n.º 30
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)

    _verifyOutput(outPath)
Exemplo n.º 31
0
    def test_getCoordinates(self):
        glyphSet = {}
        pen = TTGlyphPen(glyphSet)
        pen.moveTo((0, 0))
        pen.lineTo((100, 0))
        pen.lineTo((100, 100))
        pen.lineTo((0, 100))
        pen.closePath()
        # simple contour glyph
        glyphSet["a"] = a = pen.glyph()

        assert a.getCoordinates(glyphSet) == (
            GlyphCoordinates([(0, 0), (100, 0), (100, 100), (0, 100)]),
            [3],
            array.array("B", [1, 1, 1, 1]),
        )

        # composite glyph with only XY offset
        pen = TTGlyphPen(glyphSet)
        pen.addComponent("a", (1, 0, 0, 1, 10, 20))
        glyphSet["b"] = b = pen.glyph()

        assert b.getCoordinates(glyphSet) == (
            GlyphCoordinates([(10, 20), (110, 20), (110, 120), (10, 120)]),
            [3],
            array.array("B", [1, 1, 1, 1]),
        )

        # composite glyph with a scale (and referencing another composite glyph)
        pen = TTGlyphPen(glyphSet)
        pen.addComponent("b", (0.5, 0, 0, 0.5, 0, 0))
        glyphSet["c"] = c = pen.glyph()

        assert c.getCoordinates(glyphSet) == (
            GlyphCoordinates([(5, 10), (55, 10), (55, 60), (5, 60)]),
            [3],
            array.array("B", [1, 1, 1, 1]),
        )

        # composite glyph with unscaled offset (MS-style)
        pen = TTGlyphPen(glyphSet)
        pen.addComponent("a", (0.5, 0, 0, 0.5, 10, 20))
        glyphSet["d"] = d = pen.glyph()
        d.components[0].flags |= UNSCALED_COMPONENT_OFFSET

        assert d.getCoordinates(glyphSet) == (
            GlyphCoordinates([(10, 20), (60, 20), (60, 70), (10, 70)]),
            [3],
            array.array("B", [1, 1, 1, 1]),
        )

        # composite glyph with a scaled offset (Apple-style)
        pen = TTGlyphPen(glyphSet)
        pen.addComponent("a", (0.5, 0, 0, 0.5, 10, 20))
        glyphSet["e"] = e = pen.glyph()
        e.components[0].flags |= SCALED_COMPONENT_OFFSET

        assert e.getCoordinates(glyphSet) == (
            GlyphCoordinates([(5, 10), (55, 10), (55, 60), (5, 60)]),
            [3],
            array.array("B", [1, 1, 1, 1]),
        )

        # composite glyph where the 2nd and 3rd components use anchor points
        pen = TTGlyphPen(glyphSet)
        pen.addComponent("a", (1, 0, 0, 1, 0, 0))
        glyphSet["f"] = f = pen.glyph()

        comp1 = GlyphComponent()
        comp1.glyphName = "a"
        # aling the new component's pt 0 to pt 2 of contour points added so far
        comp1.firstPt = 2
        comp1.secondPt = 0
        comp1.flags = 0
        f.components.append(comp1)

        comp2 = GlyphComponent()
        comp2.glyphName = "a"
        # aling the new component's pt 0 to pt 6 of contour points added so far
        comp2.firstPt = 6
        comp2.secondPt = 0
        comp2.transform = [[0.707107, 0.707107], [-0.707107,
                                                  0.707107]]  # rotate 45 deg
        comp2.flags = WE_HAVE_A_TWO_BY_TWO
        f.components.append(comp2)

        coords, end_pts, flags = f.getCoordinates(glyphSet)
        assert end_pts == [3, 7, 11]
        assert flags == array.array("B", [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
        assert list(sum(coords, ())) == pytest.approx([
            0,
            0,
            100,
            0,
            100,
            100,
            0,
            100,
            100,
            100,
            200,
            100,
            200,
            200,
            100,
            200,
            200,
            200,
            270.7107,
            270.7107,
            200.0,
            341.4214,
            129.2893,
            270.7107,
        ])
Exemplo n.º 32
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
Exemplo n.º 33
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()
    glyph1 = pen.glyph()

    pen = TTGlyphPen(None)
    pen.moveTo((50, 0))
    pen.lineTo((50, 200))
    pen.lineTo((250, 200))
    pen.lineTo((250, 0))
    pen.closePath()
    glyph2 = pen.glyph()

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

    glyphs = {
        ".notdef": emptyGlyph,
        "A": glyph1,
        "a": glyph2,
        ".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.addFeatureVariations(
        [([
            {
                "LEFT": (0.8, 1),
                "DOWN": (0.8, 1)
            },
            {
                "RGHT": (0.8, 1),
                "UPPP": (0.8, 1)
            },
        ], {
            "A": "a"
        })],
        featureTag="rclt",
    )

    statAxes = []
    for tag, minVal, defaultVal, maxVal, name in axes:
        values = [
            dict(name="Neutral", value=defaultVal, flags=0x2),
            dict(name=name, value=maxVal)
        ]
        statAxes.append(dict(tag=tag, name=name, values=values))
    fb.setupStat(statAxes)

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

    fb.save(outPath)

    _verifyOutput(outPath)
Exemplo n.º 34
0
def colrv1_path(tmp_path):
    base_glyph_names = ["uni%04X" % i for i in range(0xE000, 0xE000 + 10)]
    layer_glyph_names = ["glyph%05d" % i for i in range(10, 20)]
    glyph_order = [".notdef"] + base_glyph_names + layer_glyph_names

    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(
        {int(name[3:], 16): name
         for name in base_glyph_names})
    fb.setupGlyf(glyphs)
    fb.setupHorizontalMetrics({g: (500, 0) for g in glyph_order})
    fb.setupHorizontalHeader()
    fb.setupOS2()
    fb.setupPost()
    fb.setupNameTable({"familyName": "TestCOLRv1", "styleName": "Regular"})

    fb.setupCOLR(
        {
            "uniE000": (
                ot.PaintFormat.PaintColrLayers,
                [
                    {
                        "Format": ot.PaintFormat.PaintGlyph,
                        "Paint": (ot.PaintFormat.PaintSolid, 0),
                        "Glyph": "glyph00010",
                    },
                    {
                        "Format": ot.PaintFormat.PaintGlyph,
                        "Paint": (ot.PaintFormat.PaintSolid, (2, 0.3)),
                        "Glyph": "glyph00011",
                    },
                ],
            ),
            "uniE001": (
                ot.PaintFormat.PaintColrLayers,
                [
                    {
                        "Format": ot.PaintFormat.PaintTransform,
                        "Paint": {
                            "Format": ot.PaintFormat.PaintGlyph,
                            "Paint": {
                                "Format": ot.PaintFormat.PaintRadialGradient,
                                "x0": 250,
                                "y0": 250,
                                "r0": 250,
                                "x1": 200,
                                "y1": 200,
                                "r1": 0,
                                "ColorLine": {
                                    "ColorStop": [(0.0, 1), (1.0, 2)],
                                    "Extend": "repeat",
                                },
                            },
                            "Glyph": "glyph00012",
                        },
                        "Transform": (0.7071, 0.7071, -0.7071, 0.7071, 0, 0),
                    },
                    {
                        "Format": ot.PaintFormat.PaintGlyph,
                        "Paint": (ot.PaintFormat.PaintSolid, (1, 0.5)),
                        "Glyph": "glyph00013",
                    },
                ],
            ),
            "uniE002": (
                ot.PaintFormat.PaintColrLayers,
                [
                    {
                        "Format": ot.PaintFormat.PaintGlyph,
                        "Paint": {
                            "Format": ot.PaintFormat.PaintLinearGradient,
                            "x0": 0,
                            "y0": 0,
                            "x1": 500,
                            "y1": 500,
                            "x2": -500,
                            "y2": 500,
                            "ColorLine": {
                                "ColorStop": [(0.0, 1), (1.0, 2)]
                            },
                        },
                        "Glyph": "glyph00014",
                    },
                    {
                        "Format": ot.PaintFormat.PaintTransform,
                        "Paint": {
                            "Format": ot.PaintFormat.PaintGlyph,
                            "Paint": (ot.PaintFormat.PaintSolid, 1),
                            "Glyph": "glyph00015",
                        },
                        "Transform": (1, 0, 0, 1, 400, 400),
                    },
                ],
            ),
            "uniE003": {
                "Format": ot.PaintFormat.PaintRotate,
                "Paint": {
                    "Format": ot.PaintFormat.PaintColrGlyph,
                    "Glyph": "uniE001",
                },
                "angle": 45,
                "centerX": 250,
                "centerY": 250,
            },
            "uniE004": [
                ("glyph00016", 1),
                ("glyph00017", 2),
            ],
        }, )
    fb.setupCPAL(
        [
            [
                (1.0, 0.0, 0.0, 1.0),  # red
                (0.0, 1.0, 0.0, 1.0),  # green
                (0.0, 0.0, 1.0, 1.0),  # blue
            ],
        ], )

    output_path = tmp_path / "TestCOLRv1.ttf"
    fb.save(output_path)

    return output_path