Exemplo n.º 1
0
def main(args):
    if len(args) < 3:
        sys.exit("usage: kern_table.py ufo ttf output_ttf")
    ufo_path = args[0]
    font_path = args[1]
    output_path = args[2]
    ufo = Font(ufo_path)
    font = TTFont(font_path)

    print("parsing %s to add legacy kern table to %s" % (ufo_path, font_path))

    kerning = flatten_kerning(ufo)
    print("total kerning pairs: %i" % len(kerning))
    key_kerning = flatten_kerning(ufo, key_glyphs_only=True)
    print("kerning pairs kept: %i" % len(key_kerning))

    kern = newTable("kern")
    kern.version = 0

    subtable = KernTable_format_0()
    subtable.coverage = 1
    subtable.version = 0
    subtable.kernTable = {}
    subtable.kernTable.update(key_kerning)
    kern.kernTables = [subtable]
    font["kern"] = kern
    print("writing font with legacy kern table to %s" % output_path)
    font.save(output_path)
Exemplo n.º 2
0
 def test_decompileBadGlyphId(self, font):
     subtable = KernTable_format_0()
     subtable.decompile(
         b'\x00' + b'\x00' + b'\x00' + b'\x1a' + b'\x00' + b'\x00' +
         b'\x00' + b'\x02' + b'\x00' * 6 + b'\x00' + b'\x01' + b'\x00' +
         b'\x03' + b'\x00' + b'\x01' + b'\x00' + b'\x01' + b'\xFF' +
         b'\xFF' + b'\x00' + b'\x02', font)
     assert subtable[("B", "D")] == 1
     assert subtable[("B", "glyph65535")] == 2
Exemplo n.º 3
0
 def test_decompileBadGlyphId(self):
         subtable = KernTable_format_0()
         subtable.apple = False
         subtable.decompile(  b'\x00' * 6
                            + b'\x00' + b'\x02' + b'\x00' * 6
                            + b'\x00' + b'\x01' + b'\x00' + b'\x03' + b'\x00' + b'\x01'
                            + b'\x00' + b'\x01' + b'\xFF' + b'\xFF' + b'\x00' + b'\x02',
                            MockFont())
         self.assertEqual(subtable[("glyph00001", "glyph00003")], 1)
         self.assertEqual(subtable[("glyph00001", "glyph65535")], 2)
Exemplo n.º 4
0
 def test_toXML_single_format_0(self, font, version, expected):
     kern = newTable("kern")
     kern.version = version
     apple = version == 1.0
     st = KernTable_format_0(apple)
     kern.kernTables = [st]
     st.coverage = 0 if apple else 1
     st.tupleIndex = 0 if apple else None
     st.kernTable = {('E', 'M'): -40, ('E', 'c'): 40, ('F', 'o'): -50}
     xml = getXML(kern.toXML, font)
     assert xml == expected
Exemplo n.º 5
0
 def test_compile_single_format_0(self, font, version, expected):
     kern = newTable("kern")
     kern.version = version
     apple = version == 1.0
     st = KernTable_format_0(apple)
     kern.kernTables = [st]
     st.coverage = (0 if apple else 1)
     st.tupleIndex = 0 if apple else None
     st.kernTable = {('E', 'M'): -40, ('E', 'c'): 40, ('F', 'o'): -50}
     data = kern.compile(font)
     assert data == expected
Exemplo n.º 6
0
def BuildFuColonKernSubtable(font, left, right):
    cmap = font['cmap'].getBestCmap()
    nums = [cmap[ord(i)] for i in "0123456789"]
    fuColon = cmap[ord(":")]

    kernPairs = {(fuColon, n): right for n in nums}
    if left:
        kernPairs.update({(n, fuColon): right for n in nums})

    subtable = KernTable_format_0()
    subtable.coverage = 0b00000001
    subtable.format = 0
    subtable.kernTable = kernPairs
    return subtable
Exemplo n.º 7
0
    def test_getkern(self):
        table = newTable("kern")
        table.version = 0
        table.kernTables = []

        assert table.getkern(0) is None

        st0 = KernTable_format_0()
        table.kernTables.append(st0)

        assert table.getkern(0) is st0
        assert table.getkern(4) is None

        st1 = KernTable_format_unkown(4)
        table.kernTables.append(st1)
Exemplo n.º 8
0
 def test_compileOverflowingSubtable(self, overflowing_font):
     font = overflowing_font
     kern = newTable("kern")
     kern.version = 0
     st = KernTable_format_0(0)
     kern.kernTables = [st]
     st.coverage = 1
     st.tupleIndex = None
     st.kernTable = {
         (a, b): 0
         for (a, b) in itertools.product(font.getGlyphOrder(), repeat=2)
     }
     assert len(st.kernTable) == 11025
     data = kern.compile(font)
     assert data == KERN_VER_0_FMT_0_OVERFLOWING_DATA
Exemplo n.º 9
0
def test_check_kern_table():
    """ Is there a "kern" table declared in the font? """
    check = CheckTester(opentype_profile,
                        "com.google.fonts/check/kern_table")

    # Our reference Mada Regular is known to be good
    # (does not have a 'kern' table):
    ttFont = TTFont(TEST_FILE("mada/Mada-Regular.ttf"))

    # So it must PASS the check:
    assert_PASS(check(ttFont),
                'with a font without a "kern" table...')

    # add a basic 'kern' table:
    kern = ttFont["kern"] = newTable("kern")
    kern.version = 0
    subtable = KernTable_format_0()
    subtable.coverage = 1
    subtable.version = 0
    subtable.kernTable = {("A", "V"): -50}
    kern.kernTables = [subtable]

    # and make sure the check emits an INFO message:
    assert_results_contain(check(ttFont),
                           INFO, 'kern-found',
                           'with a font containing a "kern" table...')

    # and a FAIL message when a non-character glyph is used.
    subtable.kernTable.update({("A", "four.dnom"): -50})
    assert_results_contain(check(ttFont),
                           FAIL, 'kern-non-character-glyphs',
                           'The following glyphs should not be used...')

    # and a WARN message when a non-character glyph is used.
    subtable = KernTable_format_unkown(2)
    kern.kernTables = [subtable]
    assert_results_contain(check(ttFont),
                           WARN, 'kern-unknown-format',
                           'The "kern" table does not have any format-0 subtable...')
Exemplo n.º 10
0
def processFont(path, d, flatKernData):
    font = TTFont(path)
    oldD, f = os.path.split(path)
    new = os.path.join(d, f)

    name = font['name'].getName(6, 1, 0, 0).string

    # Make a flat kerning table
    if flatKernData is not None:
        newKern = ttLib.newTable("kern")
        newKern.version = 0
        newKern.kernTables = [KernTable_format_0()]

        flat = flatKernData[name]
        sortedKeys = flat.keys()
        sortedKeys.sort()

        left = ''
        i = 0
        for key in sortedKeys:
            if left == '':
                left = key[0]
                kern_table = {key: flat[key]}
                count = _flat_kern_count(left, sortedKeys)
                i += 1
            elif i + 1 < len(sortedKeys) and left != sortedKeys[i + 1][0]:
                if count + _flat_kern_count(sortedKeys[i + 1][0],
                                            sortedKeys) > 10920:
                    kern_table[key] = flat[key]

                    t = len(newKern.kernTables) - 1

                    table = newKern.kernTables[t]
                    table.kernTable = kern_table
                    table.version = 0
                    table.coverage = 1
                    table.apple = False
                    newKern.kernTables.append(KernTable_format_0())
                    left = ''
                else:
                    kern_table[key] = flat[key]
                    left = sortedKeys[i + 1][0]
                    count = _flat_kern_count(sortedKeys[i + 1][0],
                                             sortedKeys) + count
                i += 1
            elif len(sortedKeys) == i + 1:
                kern_table[key] = flat[key]
                t = len(newKern.kernTables) - 1
                table = newKern.kernTables[t]
                table.kernTable = kern_table
                table.version = 0
                table.coverage = 1
                table.apple = False
                i += 1
            else:
                kern_table[key] = flat[key]
                i += 1

        # Add this table back to the font
        font.tables["kern"] = newKern

    # Fix the ugly id string
    versionClean(font)
    nameTableTweak(font)
    makeDSIG(font)

    font.save(new)
Exemplo n.º 11
0
def BuildGenericKernSubtable(font, cyrillic):
    scriptDflt = [
        scr for scr in font['GPOS'].table.ScriptList.ScriptRecord
        if scr.ScriptTag == 'DFLT'
    ]
    scriptDfltFeaList = [
        font['GPOS'].table.FeatureList.FeatureRecord[i]
        for i in scriptDflt[0].Script.DefaultLangSys.FeatureIndex
    ]
    kernFeaList = [
        fea.Feature for fea in scriptDfltFeaList if fea.FeatureTag == 'kern'
    ]
    kernLutList = [
        font['GPOS'].table.LookupList.Lookup[i] for fea in kernFeaList
        for i in fea.LookupListIndex
    ]

    kernPairStList = sum(
        [lut.SubTable for lut in kernLutList if lut.LookupType == 2], [])
    kernExtLutList = sum(
        [lut.SubTable for lut in kernLutList if lut.LookupType == 9], [])
    kernPairStList += [
        lut.ExtSubTable for lut in kernExtLutList
        if lut.ExtensionLookupType == 2
    ]

    # letters in Adobe Latin 1 and Adobe Cyrillic 1
    kernSubset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿıŁłŒœŠšŸŽžƒ"
    if cyrillic:
        kernSubset += "ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѢѣѲѳѴѵҐґ"

    cmap = font['cmap'].getBestCmap()
    kernGlyph = {*[cmap[ord(ch)] for ch in kernSubset]}

    kernPairs = {}

    for st in kernPairStList:
        if st.Format == 1:
            coverage = st.Coverage.glyphs
            for i in range(st.PairSetCount):
                first = coverage[i]
                if first not in kernGlyph:
                    continue
                pairSet = st.PairSet[i]
                for pairRec in pairSet.PairValueRecord:
                    second = pairRec.SecondGlyph
                    if second not in kernGlyph:
                        continue
                    value = pairRec.Value1.XAdvance
                    if value:
                        kernPairs[(first, second)] = value

        elif st.Format == 2:
            coverage = st.Coverage.glyphs
            classDef1 = st.ClassDef1.classDefs
            classDef2 = st.ClassDef2.classDefs
            for first in coverage:
                if first not in kernGlyph:
                    continue
                firstClass = classDef1.get(first, 0)
                class1Record = st.Class1Record[firstClass]
                for second in coverage:
                    if second not in kernGlyph:
                        continue
                    secondClass = classDef2.get(second, 0)
                    class2Record = class1Record.Class2Record[secondClass]
                    value = class2Record.Value1.XAdvance
                    if value:
                        kernPairs[(first, second)] = value

    subtable = KernTable_format_0()
    subtable.coverage = 0b00000001
    subtable.format = 0
    subtable.kernTable = kernPairs
    return subtable