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.
def hinting_level(self): if filter(lambda fn: os.path.basename(fn) == '.ttfautohint', self.files): return '4' for ottf in self.ottffiles: # Searches for .ttfautohint glyph inside. If glyph exists # then returns hinting_level to '3' is_glyph_existed = self.check_for_ttfautohint_glyph(ottf) if is_glyph_existed: return '4' ttfont = TTFont(ottf) try: if ttfont.getTableData("prep") is None: return '2' except KeyError: return '2' prepAsm = ttfont.getTableData("prep") prepText = fontforge.unParseTTInstrs(prepAsm) prepMagic = "PUSHW_1\n 511\nSCANCTRL\nPUSHB_1\n 4\nSCANTYPE" if prepText.strip() == prepMagic: return '2' return '1'
def getSFNTData(pathOrFile): font = TTFont(pathOrFile) # checksums tableChecksums = {} for tag, entry in font.reader.tables.items(): tableChecksums[tag] = entry.checkSum # data tableData = {} for tag in font.keys(): if len(tag) != 4: continue origData = font.getTableData(tag) compData = zlib.compress(origData) if len(compData) >= len(origData) or tag == "head": compData = origData tableData[tag] = (origData, compData) # order tableOrder = [i for i in font.keys() if len(i) == 4] font.close() del font return tableData, tableOrder, tableChecksums
# works on Mi Lan Pro VF Version 1.10, sha1sum = 7c489c6291067561733b20d2237963d6d36406d8 from fontTools.ttLib import TTFont, newTable from fontTools.varLib.varStore import VarStoreInstancer from pprint import pprint infile = "MiLanProVF.ttf" outfile = "MiLanProVF-fix.ttf" font = TTFont(infile) # fix gvar.glyphCount gvar_raw = bytearray(font.getTableData('gvar')) glyphCount = len(font['hmtx'].metrics) gvar_raw[12] = glyphCount // 256 gvar_raw[13] = glyphCount % 256 gvar_ = newTable('gvar') gvar_.decompile(bytes(gvar_raw), font) # fix phantom points in gvar fvar_ = font['fvar'] hvar_ = font['HVAR'] for name, tvl in gvar_.variations.items():
def main(args: Optional[List[str]] = None): parser = argparse.ArgumentParser() parser.add_argument("fonts", type=Path, nargs="+", help="Path to TTFs.") parsed_args = parser.parse_args(args) runtimes = defaultdict(list) rows = [] font_path: Path for font_path in parsed_args.fonts: font = TTFont(font_path) if "GPOS" not in font: print(f"No GPOS in {font_path.name}, skipping.", file=sys.stderr) continue size_orig = len(font.getTableData("GPOS")) / 1024 print(f"Measuring {font_path.name}...", file=sys.stderr) fonts = {} font_paths = {} sizes = {} for mode in MODES: print(f" Running mode={mode}", file=sys.stderr) fonts[mode] = TTFont(font_path) before = time.perf_counter() compact(fonts[mode], mode=str(mode)) runtimes[mode].append(time.perf_counter() - before) font_paths[mode] = ( font_path.parent / "compact" / (font_path.stem + f"_{mode}" + font_path.suffix)) font_paths[mode].parent.mkdir(parents=True, exist_ok=True) fonts[mode].save(font_paths[mode]) fonts[mode] = TTFont(font_paths[mode]) sizes[mode] = len(fonts[mode].getTableData("GPOS")) / 1024 print(f" Runtimes:", file=sys.stderr) for mode, times in runtimes.items(): print( f" {mode:10} {' '.join(f'{t:5.2f}' for t in times)}", file=sys.stderr, ) # Bonus: measure WOFF2 file sizes. print(f" Measuring WOFF2 sizes", file=sys.stderr) size_woff_orig = woff_size(font, font_path) / 1024 sizes_woff = { mode: woff_size(fonts[mode], font_paths[mode]) / 1024 for mode in MODES } rows.append(( font_path.name, size_orig, size_woff_orig, *flatten(( sizes[mode], pct(sizes[mode], size_orig), sizes_woff[mode], pct(sizes_woff[mode], size_woff_orig), ) for mode in MODES), )) write_csv(rows)
from fontTools.ttLib import TTFont from fontTools.ttLib.tables.DefaultTable import DefaultTable font_path = "myfont.ttf" output_path = "myfont_patched.ttf" table_tag = "DSIG" # Get raw table data from the source font font = TTFont(font_path) raw_data = font.getTableData(table_tag) # Do something with the raw table data # This example just sets an empty DSIG table. raw_data = b"\0\0\0\1\0\0\0\0" # Write the data back to the font # We could re-use the existing table when the source and target font are # identical, but let's make a new empty table to be more universal. table = DefaultTable(table_tag) table.data = raw_data # Add the new table back into the source font and save under a new name. font[table_tag] = table font.save(output_path)
def parse_font(font_file, create_texture): font = TTFont(font_file) print(font.getTableData("kern")) """ lines = iter(font.split('\n')) # find common data while True: try: line = next(lines) except StopIteration: raise BitmapFontGeneratorParseError('unable to find common line') if line.startswith('common'): common = text_to_dict(line[len('common'):]) break texture_width = common["scaleW"] texture_height = common["scaleH"] line_height = common["lineHeight"] page_count = common["pages"] if page_count > 1: logger.warning( 'multiple pages are unsupported, font may not appear correctly' ) # get page data for i in range(page_count): line = next(lines) if not line.startswith('page'): raise BitmapFontGeneratorParseError( 'expected "page" line, but got {0}'.format(line) ) page = text_to_dict(line[len('page'):]) if page["id"] == 0: texture = find_texture(page["file"]) break # find chars data while True: try: line = next(lines) except StopIteration: raise BitmapFontGeneratorParseError('unable to find chars count') if line.startswith('chars'): chars = text_to_dict(line[len('chars'):]) break character_count = chars["count"] # load each character characters = [] fallback_character_index = 0 has_newline = False for i in range(character_count): line = next(lines) if not line.startswith('char'): raise BitmapFontGeneratorParseError( 'expected "char" line, but got {0}'.format(line) ) character = text_to_dict(line[len('char'):]) if character["id"] == -1: character["id"] = 0 fallback_character_index = i elif character["id"] == ord('\n'): has_newline = True if character["page"] != 0: logger.warning( 'character {0} is on a page other than 0, but fonts only ' 'support one texture, ignoring'.format(line) ) continue if character["chnl"] != 15: logger.warning( 'character {0} is on a specific color channel, which is ' 'unsupported, it will be included, but may not appear ' 'correctly'.format(line) ) continue # calculate sik character data characters.append(( character["id"], character["x"] / texture_width, character["y"] / texture_height, (character["x"] + character["width"]) / texture_width, (character["y"] + character["height"]) / texture_width, character["id"] in break_characters, )) # add newline if it doesn't exist if not has_newline: characters.append(( ord('\n'), 0, 0, 0, 0, True )) return Font(line_height, texture, characters, fallback_character_index) """
]): 2, str([1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1]): 7, } # decrypt = decrypt_collection.find_one({"_id": 1})["match"] file_name = ttfUrl.split("/")[-1] match = {} # 获取ttf 文件 res = requests.get(ttfUrl) with open(file_name, "wb") as file: file.write(res.content) # ttf 文件解析 font = TTFont(file_name) font.get("glyf") font.getTableData("glyf") for key in font["glyf"].glyphs: f = font["glyf"].glyphs[key] if not hasattr(f, "flags"): continue if str(f.flags.tolist()) in ttfMatch: match[key.lower().replace("uni", "&#x") + ";"] = str(ttfMatch[str( f.flags.tolist())]) # 粘贴到system_config 表 print("'{}': {}".format(file_name.split(".")[0], match))