Пример #1
0
def buildCompatChars(sfd, ttf):
    zwj = u'\u200D'
    ranges = (
            (0xfb50, 0xfbb1),
            (0xfbd3, 0xfd3d),
            (0xfd50, 0xfdf9),
            (0xfdfc, 0xfdfc),
            (0xfe70, 0xfefc),
            )

    with open(ttf, "rb") as f:
        data = f.read()
        blob = HarfBuzz.glib_blob_create(GLib.Bytes.new(data))
        face = HarfBuzz.face_create(blob, 0)
        hbfont = HarfBuzz.font_create(face)
        upem = HarfBuzz.face_get_upem(face)
        HarfBuzz.font_set_scale(hbfont, upem, upem)
        HarfBuzz.ot_font_set_funcs(hbfont)

    ttfont = TTFont(ttf)

    for r in ranges:
        for c in range(r[0], r[1]+1):
            dec = ucd.decomposition(unichr(c)).split()
            if dec:
                keyword = dec[0]
                text = u''

                for i in dec[1:]:
                    text += unichr(int(str(i),16))

                if keyword == '<initial>':
                    text = text + zwj
                elif keyword == '<final>':
                    text = zwj + text
                elif keyword == '<medial>':
                    text = zwj + text + zwj

                components = shape(text, hbfont)
                if components:
                    glyph = sfd.createChar(c)
                    glyph.clear()
                    glyph.color = 0xff0000 # red color
                    x = 0
                    for component in components:
                        gid = component[0]
                        name = ttfont.getGlyphName(gid)
                        x_advance = component[1]
                        x_offset = component[2]
                        y_offset = component[3]

                        matrix = psMat.translate(x + x_offset, y_offset)

                        # ignore blank glyphs, e.g. space or ZWJ
                        if sfd[name].foreground or sfd[name].references:
                            glyph.addReference(name, matrix)

                        x += x_advance

                    glyph.width = x
Пример #2
0
def buildCompatChars(sfd, ttf):
    zwj = u'\u200D'
    ranges = (
        (0xfb50, 0xfbb1),
        (0xfbd3, 0xfd3d),
        (0xfd50, 0xfdf9),
        (0xfdfc, 0xfdfc),
        (0xfe70, 0xfefc),
    )

    with open(ttf, "rb") as f:
        data = f.read()
        blob = HarfBuzz.glib_blob_create(GLib.Bytes.new(data))
        face = HarfBuzz.face_create(blob, 0)
        hbfont = HarfBuzz.font_create(face)
        upem = HarfBuzz.face_get_upem(face)
        HarfBuzz.font_set_scale(hbfont, upem, upem)
        HarfBuzz.ot_font_set_funcs(hbfont)

    ttfont = TTFont(ttf)

    for r in ranges:
        for c in range(r[0], r[1] + 1):
            dec = ucd.decomposition(unichr(c)).split()
            if dec:
                keyword = dec[0]
                text = u''

                for i in dec[1:]:
                    text += unichr(int(str(i), 16))

                if keyword == '<initial>':
                    text = text + zwj
                elif keyword == '<final>':
                    text = zwj + text
                elif keyword == '<medial>':
                    text = zwj + text + zwj

                components = shape(text, hbfont)
                if components:
                    glyph = sfd.createChar(c)
                    glyph.clear()
                    glyph.color = 0xff0000  # red color
                    x = 0
                    for component in components:
                        gid = component[0]
                        name = ttfont.getGlyphName(gid)
                        x_advance = component[1]
                        x_offset = component[2]
                        y_offset = component[3]

                        matrix = psMat.translate(x + x_offset, y_offset)

                        # ignore blank glyphs, e.g. space or ZWJ
                        if sfd[name].foreground or sfd[name].references:
                            glyph.addReference(name, matrix)

                        x += x_advance

                    glyph.width = x
Пример #3
0
class TTXLEFont(LEFontInstance):

    def __init__(self, fname, size=12):
        super(TTXLEFont, self).__init__()

        self.ttx = TTFont(fname)
        self.size = size
        self.upem = self.ttx['head'].unitsPerEm
        self.cmap = self.ttx['cmap'].getcmap(3, 1).cmap

    def getFontTable(self, table):
        return self.ttx.getTableData(table)

    def getAscent(self):
        self.ttx['hhea'].ascent * self.size * 1. / self.upem

    def getDescent(self):
        self.ttx['hhea'].descent * self.size * 1. / self.upem

    def getLeading(self):
        self.ttx['hhea'].lineGap * self.size * 1. / self.upem

    def getUnitsPerEm(self):
        return self.upem

    def mapCharToGlyph(self, code):
        return self.ttx.getGlyphID(self.cmap[code])

    def getGlyphAdvance(self, glyph):

        if glyph >= self.ttx['maxp'].numGlyphs:
            return (0., 0.)

        name = self.ttx.getGlyphName(glyph)
        x = self.ttx['hmtx'][name][0] * self.size * 1. / self.upem

        if 'vmtx' in self.ttx:
            y = self.ttx['vmtx'][name][0] * self.size * 1. / self.upem
        else:
            y = 0.

        return (x, y)

    def getGlyphPoint(self, glyph, point):
        return (0., 0.)

    def getXPixelsPerEm(self):
        return self.size

    def getYPixelsPerEm(self):
        return self.size

    def getScaleFactorX(self):
        return 1.

    def getScaleFactorY(self):
        return 1.
Пример #4
0
class TTXLEFont(LEFontInstance):
    def __init__(self, fname, size=12):
        super(TTXLEFont, self).__init__()

        self.ttx = TTFont(fname)
        self.size = size
        self.upem = self.ttx['head'].unitsPerEm
        self.cmap = self.ttx['cmap'].getcmap(3, 1).cmap

    def getFontTable(self, table):
        return self.ttx.getTableData(table)

    def getAscent(self):
        self.ttx['hhea'].ascent * self.size * 1. / self.upem

    def getDescent(self):
        self.ttx['hhea'].descent * self.size * 1. / self.upem

    def getLeading(self):
        self.ttx['hhea'].lineGap * self.size * 1. / self.upem

    def getUnitsPerEm(self):
        return self.upem

    def mapCharToGlyph(self, code):
        return self.ttx.getGlyphID(self.cmap[code])

    def getGlyphAdvance(self, glyph):

        if glyph >= self.ttx['maxp'].numGlyphs:
            return (0., 0.)

        name = self.ttx.getGlyphName(glyph)
        x = self.ttx['hmtx'][name][0] * self.size * 1. / self.upem

        if 'vmtx' in self.ttx:
            y = self.ttx['vmtx'][name][0] * self.size * 1. / self.upem
        else:
            y = 0.

        return (x, y)

    def getGlyphPoint(self, glyph, point):
        return (0., 0.)

    def getXPixelsPerEm(self):
        return self.size

    def getYPixelsPerEm(self):
        return self.size

    def getScaleFactorX(self):
        return 1.

    def getScaleFactorY(self):
        return 1.
Пример #5
0
                 else:
                     features_string += f'  {feature_text_line}'
             features_string += f'\n}} {feature_name};\n'
 aalt_string += '} aalt;\n'
 final_string = classes_string + prefix_string + aalt_string + features_string
 # Rename glyphs within features string to match target set
 print('  Renaming features glyphs')
 with open(Path(INDEX_DIR / f'{config["inputFile"]}.json'),
           'r') as file:
     glyph_id_map = json.load(file)
 glyph_id_map_keys = sorted(glyph_id_map.keys(), reverse=True)
 for glyph_name in glyph_id_map_keys:
     regex = rf'(^|\s|\{{|\[|\\)({glyph_name})(\s|\}}|\]|\'|\;|$)'
     if re.search(regex, final_string) is not None:
         glyph_id = glyph_id_map[glyph_name]
         new_glyph_name = input_font.getGlyphName(glyph_id)
         # Run twice for instances that are sandwiched between two other instances
         for i in range(2):
             final_string = re.sub(regex,
                                   f'\g<1>{new_glyph_name}\g<3>',
                                   final_string)
 with open(Path(TEMP_DIR / 'features.fea'), 'w') as features_file:
     features_file.write(final_string)
 # Set up substitution functionality
 print('  Adding features set to output font')
 addOpenTypeFeaturesFromString(output_font, final_string)
 # Save font
 print('  Saving output font to TTF file')
 output_font.save(output_file_path)
 output_font.close()
 print(f'Completed font "{output_file_path}"')
Пример #6
0
    import icu
    icufont = TTXLEFont(sys.argv[1], ttx=tt)
    iculayout = icu.LayoutEngine(
        icufont,
        icu.ScriptCodes.index(opts.script) if opts.script else 0, 0)

lf = codecs.open(sys.argv[2], "r", "utf_8")
count = 0
for line in lf.readlines():
    count += 1
    text = line.strip()
    b = hbng.Buffer(text)
    b.shape(hbfont, shapers=["ot"])
    hbres = [x.gid for x in b.glyphs]
    s = gr.Segment(grfont, grface, 0, text, 0)
    grres = [x.gid for x in s.slots]
    if opts.compare == 'graphite':
        if hbres != grres:
            hbnres = [tt.getGlyphName(x) for x in hbres]
            grnres = [tt.getGlyphName(x) for x in grres]
            print("Failed at line %d: %s %r, %r" %
                  (count, text.encode('utf_8'), hbnres, grnres))
    elif opts.compare == "icu":
        iculayout.layoutChars(text, 0)
        icures = filter(lambda x: x != 65535, list(iculayout.getGlyphs()))
        if hbres != icures:
            hbnres = [tt.getGlyphName(x) for x in hbres]
            icunres = [tt.getGlyphName(x) for x in icures]
            print("Failed at line %d: %s %r, %r" %
                  (count, text.encode('utf_8'), hbnres, icunres))
Пример #7
0
        preview = ""
        for i in range(num_chars):
            preview += str(chr(i + start_char))
        image = Image.new("RGB", (1000, 1000))
        draw = ImageDraw.Draw(image)
        draw.text((0, 0), preview, font=font)
        image = image.crop(image.getbbox())
        image.save(args.tf + "_prev" + str(args.pt[pt]) + ".png")
        pixels = image.load()

    # Find the max and min values
    ymax = 0
    ymin = 0
    for z in range(num_chars):
        m = glyphtools.get_glyph_metrics(font_info,
                                         font_info.getGlyphName(start_id + z))
        new_ymax = (font_size * m['yMax'] / scale)
        new_ymin = (font_size * m['yMin'] / scale)
        ymin = round(min(ymin, new_ymin))
        ymax = round(max(ymax, new_ymax))
    maxmax = round(abs(ymin) + abs(ymax))

    # We are adding a new font size. Allign the start address
    if curr_offset & 3:
        curr_offset = (curr_offset + 3) & ~3

    # Add the glyph header indicating the global size of the font
    font_data += abs(ymin).to_bytes(1, byteorder="little", signed=False)
    font_data += abs(ymax).to_bytes(1, byteorder="little", signed=False)
    font_data.append(0)
    font_data.append(0)
Пример #8
0
tt = TTFont(sys.argv[1])
if opts.compare == "icu":
    from palaso.font.icule import TTXLEFont
    import icu
    icufont = TTXLEFont(sys.argv[1], ttx=tt)
    iculayout = icu.LayoutEngine(icufont, icu.ScriptCodes.index(opts.script) if opts.script else 0, 0)

lf = codecs.open(sys.argv[2], "r", "utf_8")
count = 0
for line in lf.readlines() :
    count += 1
    text = line.strip()
    b = hbng.Buffer(text)
    b.shape(hbfont, shapers=["ot"])
    hbres = [x.gid for x in b.glyphs]
    s = gr.Segment(grfont, grface, 0, text, 0)
    grres = [x.gid for x in s.slots]
    if opts.compare == 'graphite' :
        if hbres != grres :
            hbnres = [tt.getGlyphName(x) for x in hbres]
            grnres = [tt.getGlyphName(x) for x in grres]
            print("Failed at line %d: %s %r, %r" % (count, text.encode('utf_8'), hbnres, grnres))
    elif opts.compare == "icu":
        iculayout.layoutChars(text, 0)
        icures = filter(lambda x: x != 65535, list(iculayout.getGlyphs()))
        if hbres != icures :
            hbnres = [tt.getGlyphName(x) for x in hbres]
            icunres = [tt.getGlyphName(x) for x in icures]
            print("Failed at line %d: %s %r, %r" % (count, text.encode('utf_8'), hbnres, icunres))