예제 #1
0
    def test_setupTable_CFF_all_blues_defined(self, testufo):
        testufo.info.postscriptBlueFuzz = 2
        testufo.info.postscriptBlueShift = 8
        testufo.info.postscriptBlueScale = 0.049736
        testufo.info.postscriptForceBold = False
        testufo.info.postscriptBlueValues = [-12, 0, 486, 498, 712, 724]
        testufo.info.postscriptOtherBlues = [-217, -205]
        testufo.info.postscriptFamilyBlues = [-12, 0, 486, 498, 712, 724]
        testufo.info.postscriptFamilyOtherBlues = [-217, -205]

        compiler = OutlineOTFCompiler(testufo)
        compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()

        cff = compiler.otf["CFF "].cff
        private = cff[list(cff.keys())[0]].Private

        assert private.BlueFuzz == 2
        assert private.BlueShift == 8
        assert private.BlueScale == 0.049736
        assert private.ForceBold == 0
        assert private.BlueValues == [-12, 0, 486, 498, 712, 724]
        assert private.OtherBlues == [-217, -205]
        assert private.FamilyBlues == [-12, 0, 486, 498, 712, 724]
        assert private.FamilyOtherBlues == [-217, -205]
예제 #2
0
    def test_setupTable_CFF_no_blues_defined(self, testufo):
        # no blue values defined
        testufo.info.postscriptBlueValues = []
        testufo.info.postscriptOtherBlues = []
        testufo.info.postscriptFamilyBlues = []
        testufo.info.postscriptFamilyOtherBlues = []
        # the following attributes have no effect
        testufo.info.postscriptBlueFuzz = 2
        testufo.info.postscriptBlueShift = 8
        testufo.info.postscriptBlueScale = 0.049736
        testufo.info.postscriptForceBold = False

        compiler = OutlineOTFCompiler(testufo)
        compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()

        cff = compiler.otf["CFF "].cff
        private = cff[list(cff.keys())[0]].Private

        # expect default values as defined in fontTools' cffLib.py
        assert private.BlueFuzz == 1
        assert private.BlueShift == 7
        assert private.BlueScale == 0.039625
        assert private.ForceBold == 0
        # CFF PrivateDict has no blues attributes
        assert not hasattr(private, "BlueValues")
        assert not hasattr(private, "OtherBlues")
        assert not hasattr(private, "FamilyBlues")
        assert not hasattr(private, "FamilyOtherBlues")
예제 #3
0
    def test_setupTable_CFF_all_blues_defined(self):
        self.ufo.info.postscriptBlueFuzz = 2
        self.ufo.info.postscriptBlueShift = 8
        self.ufo.info.postscriptBlueScale = 0.049736
        self.ufo.info.postscriptForceBold = False
        self.ufo.info.postscriptBlueValues = [-12, 0, 486, 498, 712, 724]
        self.ufo.info.postscriptOtherBlues = [-217, -205]
        self.ufo.info.postscriptFamilyBlues = [-12, 0, 486, 498, 712, 724]
        self.ufo.info.postscriptFamilyOtherBlues = [-217, -205]

        compiler = OutlineOTFCompiler(self.ufo)
        compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()

        cff = compiler.otf["CFF "].cff
        private = cff[list(cff.keys())[0]].Private

        self.assertEqual(private.BlueFuzz, 2)
        self.assertEqual(private.BlueShift, 8)
        self.assertEqual(private.BlueScale, 0.049736)
        self.assertEqual(private.ForceBold, False)
        self.assertEqual(private.BlueValues, [-12, 0, 486, 498, 712, 724])
        self.assertEqual(private.OtherBlues, [-217, -205])
        self.assertEqual(private.FamilyBlues, [-12, 0, 486, 498, 712, 724])
        self.assertEqual(private.FamilyOtherBlues, [-217, -205])
예제 #4
0
    def test_setupTable_CFF_round_some(self, testufo):
        # only floats 'close enough' are rounded to integer
        compiler = OutlineOTFCompiler(testufo, roundTolerance=0.34)
        otf = compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()
        program = self.get_charstring_program(otf, "d")

        self.assertProgramEqual(
            program,
            [
                -26,
                150.66,
                197,
                "rmoveto",
                -33.66,
                -27,
                -27,
                -33,
                -33,
                27,
                -27,
                33.66,
                33.34,
                26.65,
                27,
                33,
                33,
                -26.65,
                27,
                -33.34,
                "hvcurveto",
                "endchar",
            ],
        )
예제 #5
0
    def test_setupTable_CFF_round_none(self, testufo):
        # roundTolerance=0 means 'don't round, keep all floats'
        compiler = OutlineOTFCompiler(testufo, roundTolerance=0)
        otf = compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()
        program = self.get_charstring_program(otf, "d")

        self.assertProgramEqual(
            program,
            [
                -26,
                150.66,
                197.32,
                "rmoveto",
                -33.66,
                -26.67,
                -26.99,
                -33.33,
                -33.33,
                26.67,
                -26.66,
                33.66,
                33.33,
                26.66,
                26.66,
                33.33,
                33.33,
                -26.66,
                26.99,
                -33.33,
                "hvcurveto",
                "endchar",
            ],
        )
예제 #6
0
 def test_importTTX(self):
     compiler = OutlineOTFCompiler(self.ufo)
     otf = compiler.otf = TTFont(sfntVersion="OTTO")
     compiler.importTTX()
     self.assertIn("CUST", otf)
     self.assertEqual(otf["CUST"].data, b"\x00\x01\xbe\xef")
     self.assertEqual(otf.sfntVersion, "OTTO")
예제 #7
0
 def test_importTTX(self, testufo):
     compiler = OutlineOTFCompiler(testufo)
     otf = compiler.otf = TTFont(sfntVersion="OTTO")
     compiler.importTTX()
     assert "CUST" in otf
     assert otf["CUST"].data == b"\x00\x01\xbe\xef"
     assert otf.sfntVersion == "OTTO"
예제 #8
0
    def test_setupTable_CFF_no_blues_defined(self):
        # no blue values defined
        self.ufo.info.postscriptBlueValues = []
        self.ufo.info.postscriptOtherBlues = []
        self.ufo.info.postscriptFamilyBlues = []
        self.ufo.info.postscriptFamilyOtherBlues = []
        # the following attributes have no effect
        self.ufo.info.postscriptBlueFuzz = 2
        self.ufo.info.postscriptBlueShift = 8
        self.ufo.info.postscriptBlueScale = 0.049736
        self.ufo.info.postscriptForceBold = False

        compiler = OutlineOTFCompiler(self.ufo)
        compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()

        cff = compiler.otf["CFF "].cff
        private = cff[list(cff.keys())[0]].Private

        # expect default values as defined in fontTools' cffLib.py
        self.assertEqual(private.BlueFuzz, 1)
        self.assertEqual(private.BlueShift, 7)
        self.assertEqual(private.BlueScale, 0.039625)
        self.assertEqual(private.ForceBold, False)
        # CFF PrivateDict has no blues attributes
        self.assertFalse(hasattr(private, "BlueValues"))
        self.assertFalse(hasattr(private, "OtherBlues"))
        self.assertFalse(hasattr(private, "FamilyBlues"))
        self.assertFalse(hasattr(private, "FamilyOtherBlues"))
예제 #9
0
 def test_no_contour_glyphs(self):
     for glyph in self.ufo:
         glyph.clearContours()
     compiler = OutlineOTFCompiler(self.ufo)
     compiler.compile()
     self.assertEqual(compiler.otf['hhea'].advanceWidthMax, 600)
     self.assertEqual(compiler.otf['hhea'].minLeftSideBearing, 0)
     self.assertEqual(compiler.otf['hhea'].minRightSideBearing, 0)
     self.assertEqual(compiler.otf['hhea'].xMaxExtent, 0)
예제 #10
0
 def test_no_contour_glyphs(self, testufo):
     for glyph in testufo:
         glyph.clearContours()
     compiler = OutlineOTFCompiler(testufo)
     compiler.compile()
     assert compiler.otf["hhea"].advanceWidthMax == 600
     assert compiler.otf["hhea"].minLeftSideBearing == 0
     assert compiler.otf["hhea"].minRightSideBearing == 0
     assert compiler.otf["hhea"].xMaxExtent == 0
예제 #11
0
    def test_setupTable_CFF_no_optimize(self, testufo):
        compiler = OutlineOTFCompiler(testufo, optimizeCFF=False)
        otf = compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()
        program = self.get_charstring_program(otf, "a")

        self.assertProgramEqual(
            program,
            [-12, 66, 0, "rmoveto", 256, 0, "rlineto", -128, 510, "rlineto", "endchar"],
        )
예제 #12
0
    def test_setupTable_CFF_round_all(self):
        # by default all floats are rounded to integer
        compiler = OutlineOTFCompiler(self.ufo)
        otf = compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()
        # glyph 'd' in TestFont.ufo contains float coordinates
        program = self.get_charstring_program(otf, "d")

        self.assertProgramEqual(program, [
            -26, 151, 197, 'rmoveto', -34, -27, -27, -33, -33, 27, -27, 34, 33,
            27, 27, 33, 33, -27, 27, -33, 'hvcurveto', 'endchar'
        ])
예제 #13
0
def test_calcCodePageRanges(emptyufo, unicodes, expected):
    font = emptyufo
    for i, c in enumerate(unicodes):
        font.newGlyph("glyph%d" % i).unicode = ord(c)

    compiler = OutlineOTFCompiler(font)
    compiler.compile()

    assert compiler.otf["OS/2"].ulCodePageRange1 == intListToNum(expected,
                                                                 start=0,
                                                                 length=32)
    assert compiler.otf["OS/2"].ulCodePageRange2 == intListToNum(expected,
                                                                 start=32,
                                                                 length=32)
예제 #14
0
    def test_cmap_nonBMP_with_UVS(self, testufo):
        u1F170 = testufo.newGlyph("u1F170")
        u1F170.unicode = 0x1F170
        testufo.newGlyph("u1F170.text")
        testufo.lib["public.unicodeVariationSequences"] = {
            "FE0E": {
                "1F170": "u1F170.text",
            },
            "FE0F": {
                "1F170": "u1F170",
            },
        }

        compiler = OutlineOTFCompiler(testufo)
        otf = compiler.compile()

        assert "cmap" in otf
        cmap = otf["cmap"]
        cmap.compile(otf)
        assert len(cmap.tables) == 5
        cmap4_0_3 = cmap.tables[0]
        cmap12_0_4 = cmap.tables[1]
        cmap14_0_5 = cmap.tables[2]
        cmap4_3_1 = cmap.tables[3]
        cmap12_3_10 = cmap.tables[4]

        assert (cmap4_0_3.platformID, cmap4_0_3.platEncID) == (0, 3)
        assert (cmap4_3_1.platformID, cmap4_3_1.platEncID) == (3, 1)
        assert cmap4_0_3.language == cmap4_3_1.language
        assert cmap4_0_3.language == 0
        mapping = {c: chr(c) for c in range(0x61, 0x6D)}
        mapping[0x20] = "space"
        assert cmap4_0_3.cmap == cmap4_3_1.cmap
        assert cmap4_0_3.cmap == mapping

        assert (cmap12_0_4.platformID, cmap12_0_4.platEncID) == (0, 4)
        assert (cmap12_3_10.platformID, cmap12_3_10.platEncID) == (3, 10)
        assert cmap12_0_4.language == cmap12_3_10.language
        assert cmap12_0_4.language == 0
        mapping[0x1F170] = "u1F170"
        assert cmap12_0_4.cmap == cmap12_3_10.cmap
        assert cmap12_0_4.cmap == mapping

        assert (cmap14_0_5.platformID, cmap14_0_5.platEncID) == (0, 5)
        assert cmap14_0_5.language == 0
        assert cmap14_0_5.uvsDict == {
            0xFE0E: [(0x1F170, "u1F170.text")],
            0xFE0F: [(0x1F170, None)],
        }
예제 #15
0
    def test_setupTable_CFF_round_some(self):
        # only floats 'close enough' are rounded to integer
        compiler = OutlineOTFCompiler(self.ufo, roundTolerance=0.1)
        otf = compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()
        program = self.get_charstring_program(otf, "d")

        # e.g., 26.99 becomes 27, but 150.66 stays as it is
        self.assertProgramEqual(program, [
            -26, 150.66, 197.32, 'rmoveto',
            -33.66, 0, -26.67, -27, 0, -33.33, 'rrcurveto',
            0, -33.33, 26.67, -26.67, 33.66, 0, 'rrcurveto',
            33.34, 0, 26.65, 26.67, 0, 33.33, 'rrcurveto',
            0, 33.33, -26.65, 27, -33.34, 0, 'rrcurveto',
            'endchar'])
예제 #16
0
 def test_makeGlyphsBoundingBoxes(self):
     # the call to 'makeGlyphsBoundingBoxes' happen in the __init__ method
     compiler = OutlineOTFCompiler(self.ufo)
     # with default roundTolerance, all coordinates and hence the bounding
     # box values are rounded with round()
     self.assertEqual(compiler.glyphBoundingBoxes['d'],
                      (90, 77, 211, 197))
예제 #17
0
 def test_makeGlyphsBoundingBoxes_floats(self):
     # specifying a custom roundTolerance affects which coordinates are
     # rounded; in this case, the top-most Y coordinate stays a float
     # (197.32), hence the bbox.yMax (198) is rounded using math.ceiling()
     compiler = OutlineOTFCompiler(self.ufo, roundTolerance=0.1)
     self.assertEqual(compiler.glyphBoundingBoxes['d'],
                      (90, 77, 211, 198))
예제 #18
0
    def test_cmap_BMP(self, testufo):
        compiler = OutlineOTFCompiler(testufo)
        otf = compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_cmap()

        assert "cmap" in otf
        cmap = otf["cmap"]
        assert len(cmap.tables) == 2
        cmap4_0_3 = cmap.tables[0]
        cmap4_3_1 = cmap.tables[1]

        assert (cmap4_0_3.platformID, cmap4_0_3.platEncID) == (0, 3)
        assert (cmap4_3_1.platformID, cmap4_3_1.platEncID) == (3, 1)
        assert cmap4_0_3.language == cmap4_3_1.language
        assert cmap4_0_3.language == 0
        mapping = {c: chr(c) for c in range(0x61, 0x6D)}
        mapping[0x20] = "space"
        assert cmap4_0_3.cmap == cmap4_3_1.cmap
        assert cmap4_0_3.cmap == mapping
예제 #19
0
    def test_setupTable_CFF_optimize(self, testufo):
        compiler = OutlineOTFCompiler(testufo, optimizeCFF=True)
        otf = compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()
        program = self.get_charstring_program(otf, "a")

        self.assertProgramEqual(
            program,
            [
                -12,
                66,
                'hmoveto',
                256,
                'hlineto',
                -128,
                510,
                'rlineto',
                'endchar'
            ]
        )
예제 #20
0
    def test_setupTable_CFF_some_blues_defined(self):
        self.ufo.info.postscriptBlueFuzz = 2
        self.ufo.info.postscriptForceBold = True
        self.ufo.info.postscriptBlueValues = []
        self.ufo.info.postscriptOtherBlues = [-217, -205]
        self.ufo.info.postscriptFamilyBlues = []
        self.ufo.info.postscriptFamilyOtherBlues = []

        compiler = OutlineOTFCompiler(self.ufo)
        compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()

        cff = compiler.otf["CFF "].cff
        private = cff[list(cff.keys())[0]].Private

        self.assertEqual(private.BlueFuzz, 2)
        self.assertEqual(private.BlueShift, 7)  # default
        self.assertEqual(private.BlueScale, 0.039625)  # default
        self.assertEqual(private.ForceBold, True)
        self.assertFalse(hasattr(private, "BlueValues"))
        self.assertEqual(private.OtherBlues, [-217, -205])
        self.assertFalse(hasattr(private, "FamilyBlues"))
        self.assertFalse(hasattr(private, "FamilyOtherBlues"))
예제 #21
0
    def test_setupTable_CFF_some_blues_defined(self, testufo):
        testufo.info.postscriptBlueFuzz = 2
        testufo.info.postscriptForceBold = True
        testufo.info.postscriptBlueValues = []
        testufo.info.postscriptOtherBlues = [-217, -205]
        testufo.info.postscriptFamilyBlues = []
        testufo.info.postscriptFamilyOtherBlues = []

        compiler = OutlineOTFCompiler(testufo)
        compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_CFF()

        cff = compiler.otf["CFF "].cff
        private = cff[list(cff.keys())[0]].Private

        assert private.BlueFuzz == 2
        assert private.BlueShift == 7  # default
        assert private.BlueScale == 0.039625  # default
        assert private.ForceBold is True
        assert not hasattr(private, "BlueValues")
        assert private.OtherBlues == [-217, -205]
        assert not hasattr(private, "FamilyBlues")
        assert not hasattr(private, "FamilyOtherBlues")
예제 #22
0
    def test_optimized_default_and_nominal_widths(self, FontClass):
        ufo = FontClass()
        ufo.info.unitsPerEm = 1000
        for glyphName, width in (
            (".notdef", 500),
            ("space", 250),
            ("a", 388),
            ("b", 410),
            ("c", 374),
            ("d", 374),
            ("e", 388),
            ("f", 410),
            ("g", 388),
            ("h", 410),
            ("i", 600),
            ("j", 600),
            ("k", 600),
            ("l", 600),
        ):
            glyph = ufo.newGlyph(glyphName)
            glyph.width = width

        compiler = OutlineOTFCompiler(ufo)
        compiler.otf = TTFont(sfntVersion="OTTO")

        compiler.setupTable_hmtx()
        compiler.setupTable_CFF()

        cff = compiler.otf["CFF "].cff
        topDict = cff[list(cff.keys())[0]]
        private = topDict.Private

        assert private.defaultWidthX == 600
        assert private.nominalWidthX == 303

        charStrings = topDict.CharStrings
        # the following have width == defaultWidthX, so it's omitted
        for g in ("i", "j", "k", "l"):
            assert charStrings.getItemAndSelector(g)[0].program == ["endchar"]
        # 'space' has width 250, so the width encoded in its charstring is:
        # 250 - nominalWidthX
        assert charStrings.getItemAndSelector("space")[0].program == [
            -53, "endchar"
        ]
예제 #23
0
 def test_makeGlyphsBoundingBoxes(self, testufo):
     compiler = OutlineOTFCompiler(testufo)
     # with default roundTolerance, all coordinates and hence the bounding
     # box values are rounded with otRound()
     assert compiler.glyphBoundingBoxes["d"] == (90, 77, 211, 197)