def execute(self, pipedata): task = self.bakery.logging_task('Optimizing TTF') if self.bakery.forcerun: return try: for filename in pipedata['bin_files']: # convert the ttf to a ttx file - this may fail font = fontforge.open(op.join(self.builddir, filename)) glyphs = [] for g in font.glyphs(): if not g.codepoint: continue glyphs.append(g.codepoint) from fontTools import subset args = [op.join(self.builddir, filename)] + glyphs args += ['--layout-features="*"'] subset.main(args) self.bakery.logging_cmd('pyftsubset %s' % ' '.join(args)) # compare filesizes TODO print analysis of this :) comment = "# look at the size savings of that subset process" cmd = "ls -l '%s'* %s" % (filename, comment) run(cmd, cwd=self.builddir, log=self.bakery.log) # move ttx files to src shutil.move(op.join(self.builddir, filename + '.subset'), op.join(self.builddir, filename), log=self.bakery.log) self.bakery.logging_task_done(task) except: self.bakery.logging_task_done(task, failed=True) raise
def optimize(self, builddir): filename = self.postscript_fontname # convert the ttf to a ttx file - this may fail font = fontforge.open(op.join(builddir, filename) + '.ttf') glyphs = [] for g in font.glyphs(): if not g.codepoint: continue glyphs.append(g.codepoint) from fontTools import subset args = [op.join(builddir, filename) + '.ttf'] + glyphs args += ['--layout-features="*"'] subset.main(args) self.stdout_pipe.write('$ pyftsubset %s' % ' '.join(args)) # compare filesizes TODO print analysis of this :) comment = "# look at the size savings of that subset process" cmd = "ls -l '%s.ttf'* %s" % (filename, comment) run(cmd, cwd=builddir, log=self.stdout_pipe) # move ttx files to src shutil.move(op.join(builddir, filename + '.ttf.subset'), op.join(builddir, filename + '.ttf'), log=self.stdout_pipe)
def test_retain_gids_cff2(self): ttx_path = self.getpath("../../varLib/data/master_ttx_varfont_otf/TestCFF2VF.ttx") font, fontpath = self.compile_font(ttx_path, ".otf") self.assertEqual(font["hmtx"]["A"], (600, 31)) self.assertEqual(font["hmtx"]["T"], (600, 41)) font["CFF2"].cff[0].decompileAllCharStrings() cs = font["CFF2"].cff[0].CharStrings self.assertGreater(len(cs["A"].program), 0) self.assertGreater(len(cs["T"].program), 0) subsetpath = self.temp_path(".otf") subset.main( [ fontpath, "--retain-gids", "--output-file=%s" % subsetpath, "T", ] ) subsetfont = TTFont(subsetpath) self.assertEqual(len(subsetfont.getGlyphOrder()), len(font.getGlyphOrder()[0:3])) hmtx = subsetfont["hmtx"] self.assertEqual(hmtx["glyph00001"], ( 0, 0)) self.assertEqual(hmtx["T"], (600, 41)) subsetfont["CFF2"].cff[0].decompileAllCharStrings() cs = subsetfont["CFF2"].cff[0].CharStrings self.assertEqual(cs["glyph00001"].program, []) self.assertGreater(len(cs["T"].program), 0)
def optimize_ttx(self, builddir): filename = self.postscript_fontname # convert the ttf to a ttx file - this may fail font = fontforge.open(op.join(builddir, filename) + '.ttf') glyphs = [] for g in font.glyphs(): if not g.codepoint: continue glyphs.append(g.codepoint) from fontTools import subset args = [op.join(builddir, filename) + '.ttf'] + glyphs # args += ['--notdef-outline', '--name-IDs="*"', '--hinting'] subset.main(args) self.stdout_pipe.write(' '.join(args)) # compare filesizes TODO print analysis of this :) cmd = "ls -l '%s.ttf'*" % filename run(cmd, cwd=builddir, log=self.stdout_pipe) # move ttx files to src shutil.move(op.join(builddir, filename + '.ttf.subset'), op.join(builddir, filename + '.ttf'), log=self.stdout_pipe)
def execute(self, pipedata, prefix=""): self.stdout_pipe.write('Optimizing TTF', prefix='### %s ' % prefix) for filename in pipedata['bin_files']: # convert the ttf to a ttx file - this may fail font = fontforge.open(op.join(self.builddir, filename)) glyphs = [] for g in font.glyphs(): if not g.codepoint: continue glyphs.append(g.codepoint) from fontTools import subset args = [op.join(self.builddir, filename)] + glyphs args += ['--layout-features="*"'] subset.main(args) self.stdout_pipe.write('$ pyftsubset %s' % ' '.join(args)) # compare filesizes TODO print analysis of this :) comment = "# look at the size savings of that subset process" cmd = "ls -l '%s'* %s" % (filename, comment) run(cmd, cwd=self.builddir, log=self.stdout_pipe) # move ttx files to src shutil.move(op.join(self.builddir, filename + '.subset'), op.join(self.builddir, filename), log=self.stdout_pipe)
def test_google_color_all(self): _, fontpath = self.compile_font(self.getpath("google_color.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=*", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.assertTrue("x" in subsetfont['CBDT'].strikeData[0]) self.assertTrue("y" in subsetfont['CBDT'].strikeData[0])
def test_subset_lcar_format_1(self): _, fontpath = self.compile_font(self.getpath("TestLCAR-1.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=U+FB01", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_lcar_1.ttx"), ["lcar"])
def test_retain_gids_ttf(self): _, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf") font = TTFont(fontpath) self.assertEqual(font["hmtx"]["A"], (500, 132)) self.assertEqual(font["hmtx"]["B"], (400, 132)) self.assertGreater(font["glyf"]["A"].numberOfContours, 0) self.assertGreater(font["glyf"]["B"].numberOfContours, 0) subsetpath = self.temp_path(".ttf") subset.main( [ fontpath, "--retain-gids", "--output-file=%s" % subsetpath, "--glyph-names", "B", ] ) subsetfont = TTFont(subsetpath) self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()[0:3]) hmtx = subsetfont["hmtx"] self.assertEqual(hmtx["A"], ( 0, 0)) self.assertEqual(hmtx["B"], (400, 132)) glyf = subsetfont["glyf"] self.assertEqual(glyf["A"].numberOfContours, 0) self.assertGreater(glyf["B"].numberOfContours, 0)
def test_notdef_width_cid(self): # https://github.com/fonttools/fonttools/pull/845 _, fontpath = self.compile_font(self.getpath("NotdefWidthCID-Regular.ttx"), ".otf") subsetpath = self.temp_path(".otf") subset.main([fontpath, "--no-notdef-outline", "--gids=0,1", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_notdef_width_cid.ttx"), ["CFF "])
def test_retain_gids_cff(self): _, fontpath = self.compile_font(self.getpath("TestOTF-Regular.ttx"), ".otf") font = TTFont(fontpath) self.assertEqual(font["hmtx"]["A"], (500, 132)) self.assertEqual(font["hmtx"]["B"], (400, 132)) font["CFF "].cff[0].decompileAllCharStrings() cs = font["CFF "].cff[0].CharStrings self.assertGreater(len(cs["A"].program), 0) self.assertGreater(len(cs["B"].program), 0) subsetpath = self.temp_path(".otf") subset.main( [ fontpath, "--retain-gids", "--output-file=%s" % subsetpath, "--glyph-names", "A", ] ) subsetfont = TTFont(subsetpath) self.assertEqual(subsetfont.getGlyphOrder(), font.getGlyphOrder()) hmtx = subsetfont["hmtx"] self.assertEqual(hmtx["A"], (500, 132)) self.assertEqual(hmtx["B"], (0, 0)) subsetfont["CFF "].cff[0].decompileAllCharStrings() cs = subsetfont["CFF "].cff[0].CharStrings self.assertGreater(len(cs["A"].program), 0) self.assertEqual(cs["B"].program, ["endchar"])
def test_subset_clr(self): _, fontpath = self.compile_font(self.getpath("TestCLR-Regular.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--glyphs=smileface", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx( subsetfont, self.getpath("expect_keep_colr.ttx"), ["GlyphOrder", "hmtx", "glyf", "COLR", "CPAL"] )
def test_subset_bsln_format_2(self): # The 'bsln' table in TestBSLN-2 refers to control points in glyph 'P' # for defining its baselines. Therefore, the subsetted font should # include this glyph even though it is not requested explicitly. _, fontpath = self.compile_font(self.getpath("TestBSLN-2.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--glyphs=one", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_bsln_2.ttx"), ["bsln"])
def test_subset_lcar_format_1(self): _, fontpath = self.compile_font(self.getpath("TestLCAR-1.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main( [fontpath, "--unicodes=U+FB01", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_lcar_1.ttx"), ["lcar"])
def test_subset_prop_remove_default_zero(self): # If all glyphs have an AAT glyph property with value 0, # the "prop" table should be removed from the subsetted font. _, fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=U+0041", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.assertNotIn("prop", subsetfont)
def test_no_hinting_desubroutinize_CFF(self): ttxpath = self.getpath("test_hinted_subrs_CFF.ttx") _, fontpath = self.compile_font(ttxpath, ".otf") subsetpath = self.temp_path(".otf") subset.main([fontpath, "--no-hinting", "--desubroutinize", "--notdef-outline", "--output-file=%s" % subsetpath, "*"]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath( "expect_no_hinting_desubroutinize_CFF.ttx"), ["CFF "])
def test_google_color(self): _, fontpath = self.compile_font(self.getpath("google_color.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--gids=0,1", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.assertTrue("CBDT" in subsetfont) self.assertTrue("CBLC" in subsetfont) self.assertTrue("x" in subsetfont['CBDT'].strikeData[0]) self.assertFalse("y" in subsetfont['CBDT'].strikeData[0])
def test_subset_bsln_format_0(self): _, fontpath = self.compile_font(self.getpath("TestBSLN-0.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main( [fontpath, "--glyphs=one", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_bsln_0.ttx"), ["bsln"])
def test_subset_prop_1(self): # If not all glyphs share the same AAT glyph properties, the subsetted # font should contain a "prop" table in format 1. To save space, the # DefaultProperties should be set to the most frequent value. _, fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=U+0030-0032", "--notdef-outline", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_prop_1.ttx"), ["prop"])
def test_no_hinting_TTF(self): _, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--no-hinting", "--notdef-outline", "--output-file=%s" % subsetpath, "*"]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath( "expect_no_hinting_TTF.ttx"), ["glyf", "maxp"]) for tag in subset.Options().hinting_tables: self.assertTrue(tag not in subsetfont)
def test_subset_opbd_remove(self): # In the test font, only the glyphs 'A' and 'zero' have an entry in # the Optical Bounds table. When subsetting, we do not request any # of those glyphs. Therefore, the produced subsetted font should # not contain an 'opbd' table. _, fontpath = self.compile_font(self.getpath("TestOPBD-0.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--glyphs=one", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.assertNotIn("opbd", subsetfont)
def test_subset_context_subst_format_3(self): # https://github.com/fonttools/fonttools/issues/1879 # Test font contains 'calt' feature with Format 3 ContextSubst lookup subtables ttx = self.getpath("TestContextSubstFormat3.ttx") font, fontpath = self.compile_font(ttx, ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=*", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) # check all glyphs are kept via GSUB closure, no changes expected self.expect_ttx(subsetfont, ttx)
def test_subset_gvar(self): _, fontpath = self.compile_font(self.getpath("TestGVAR.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([ fontpath, "--unicodes=U+002B,U+2212", "--output-file=%s" % subsetpath ]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_keep_gvar.ttx"), ["GlyphOrder", "avar", "fvar", "gvar", "name"])
def test_google_color_all(self): _, fontpath = self.compile_font(self.getpath("google_color.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main( [fontpath, "--unicodes=*", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.assertTrue("x" in subsetfont['CBDT'].strikeData[0]) self.assertTrue("y" in subsetfont['CBDT'].strikeData[0])
def test_subset_clr(self): _, fontpath = self.compile_font(self.getpath("TestCLR-Regular.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main( [fontpath, "--glyphs=smileface", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_keep_colr.ttx"), ["GlyphOrder", "hmtx", "glyf", "COLR", "CPAL"])
def test_non_BMP_text_arg_input(self): _, fontpath = self.compile_font( self.getpath("TestTTF-Regular_non_BMP_char.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") text = tostr(u"A\U0001F6D2", encoding='utf-8') subset.main([fontpath, "--text=%s" % text, "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.assertEqual(subsetfont['maxp'].numGlyphs, 3) self.assertEqual(subsetfont.getGlyphOrder(), ['.notdef', 'A', 'u1F6D2'])
def test_subset_math(self): _, fontpath = self.compile_font(self.getpath("TestMATH-Regular.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([ fontpath, "--unicodes=U+0041,U+0028,U+0302,U+1D400,U+1D435", "--output-file=%s" % subsetpath ]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_keep_math.ttx"), ["GlyphOrder", "CFF ", "MATH", "hmtx"])
def test_HVAR_VVAR_retain_gids(self): _, fontpath = self.compile_font(self.getpath("TestHVVAR.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([ fontpath, "--text=BD", "--retain-gids", "--output-file=%s" % subsetpath ]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_HVVAR_retain_gids.ttx"), ["GlyphOrder", "HVAR", "VVAR", "avar", "fvar"])
def test_notdef_width_cid(self): # https://github.com/fonttools/fonttools/pull/845 _, fontpath = self.compile_font( self.getpath("NotdefWidthCID-Regular.ttx"), ".otf") subsetpath = self.temp_path(".otf") subset.main([ fontpath, "--no-notdef-outline", "--gids=0,1", "--output-file=%s" % subsetpath ]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_notdef_width_cid.ttx"), ["CFF "])
def test_layout_scripts(self): _, fontpath = self.compile_font(self.getpath("layout_scripts.ttx"), ".otf") subsetpath = self.temp_path(".otf") subset.main([ fontpath, "--glyphs=*", "--layout-features=*", "--layout-scripts=latn,arab.URD,arab.dflt", "--output-file=%s" % subsetpath ]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_layout_scripts.ttx"), ["GPOS", "GSUB"])
def test_no_notdef_outline_cid(self): _, fontpath = self.compile_font(self.getpath("TestCID-Regular.ttx"), ".otf") subsetpath = self.temp_path(".otf") subset.main([ fontpath, "--no-notdef-outline", "--gids=0", "--output-file=%s" % subsetpath ]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_no_notdef_outline_cid.ttx"), ["CFF "])
def test_subset_prop_0(self): # If all glyphs share the same AAT glyph properties, the "prop" table # in the subsetted font should use format 0. # # Unless the shared value is zero, in which case the subsetted font # should have no "prop" table at all. But that case has already been # tested above in test_subset_prop_remove_default_zero(). _, fontpath = self.compile_font(self.getpath("TestPROP.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=U+0030-0032", "--no-notdef-glyph", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_prop_0.ttx"), ["prop"])
def test_subset_bsln_format_0_from_format_1(self): # TestBSLN-1 defines the ideographic baseline to be the font's default, # and specifies that glyphs {.notdef, zero, one, two} use the roman # baseline instead of the default ideographic baseline. As we request # a subsetted font with {zero, one} and the implicit .notdef, all # glyphs in the resulting font use the Roman baseline. In this case, # we expect a format 0 'bsln' table because it is the most compact. _, fontpath = self.compile_font(self.getpath("TestBSLN-1.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=U+0030-0031", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_bsln_0.ttx"), ["bsln"])
def test_subset_bsln_format_2_from_format_3(self): # TestBSLN-3 defines the ideographic baseline to be the font's default, # and specifies that glyphs {.notdef, zero, one, two, P} use the roman # baseline instead of the default ideographic baseline. As we request # a subsetted font with zero and the implicit .notdef and P for # baseline measurement, all glyphs in the resulting font use the Roman # baseline. In this case, we expect a format 2 'bsln' table because it # is the most compact encoding. _, fontpath = self.compile_font(self.getpath("TestBSLN-3.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=U+0030", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_bsln_2.ttx"), ["bsln"])
def test_recalc_timestamp_otf(self): ttxpath = self.getpath("TestOTF-Regular.ttx") font = TTFont() font.importXML(ttxpath) modified = font['head'].modified _, fontpath = self.compile_font(ttxpath, ".otf") subsetpath = self.temp_path(".otf") # by default, the subsetter does not recalculate the modified timestamp subset.main([fontpath, "--output-file=%s" % subsetpath, "*"]) self.assertEqual(modified, TTFont(subsetpath)['head'].modified) subset.main([fontpath, "--recalc-timestamp", "--output-file=%s" % subsetpath, "*"]) self.assertLess(modified, TTFont(subsetpath)['head'].modified)
def test_subset_bsln_format_3(self): # TestBSLN-3 defines the ideographic baseline to be the font's default, # and specifies that glyphs {.notdef, zero, one, two} use the roman # baseline instead of the default ideographic baseline. We request # a subset where the majority of glyphs use the roman baseline, # but one single glyph (uni2EA2) is ideographic. In the resulting # subsetted font, we expect a format 1 'bsln' table whose default # is Roman, but with an override that uses the ideographic baseline # for uni2EA2. _, fontpath = self.compile_font(self.getpath("TestBSLN-3.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--unicodes=U+0030-0031,U+2EA2", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) self.expect_ttx(subsetfont, self.getpath("expect_bsln_3.ttx"), ["bsln"])
def test_subset_svg_empty_table(empty_svg_font, tmp_path): font = empty_svg_font svg = new_svg() etree.SubElement(svg, "rect", {"id": "glyph1", "x": "1", "y": "2"}) font["SVG "].docList.append((etree.tostring(svg).decode(), 1, 1)) svg_font_path = tmp_path / "TestSVG.ttf" font.save(svg_font_path) subset_path = svg_font_path.with_suffix(".subset.ttf") # there's no gid=2 in SVG table, drop the empty table subset.main( [str(svg_font_path), f"--output-file={subset_path}", f"--gids=2"]) assert "SVG " not in TTFont(subset_path)
def main(input_font, output, casts, exclude_ascii): # Build list of unicode codepoints that the asciinema casts require cast_chars = set() if os.path.isfile(casts): with open(casts, 'r') as f: cast_chars = set(_get_cast_chars(f)) else: for cast_file in glob.iglob(os.path.join(casts, '**', '*.cast'), recursive=True): with open(cast_file, 'r') as f: cast_chars = cast_chars.union(set(_get_cast_chars(f))) # Exclude ascii chars (0-127)? If the font you are including is only # for glyphs then you don't really need them. if exclude_ascii: cast_chars -= { c for chars in [string.ascii_letters, string.digits, string.punctuation] for c in chars } # Exclude whitespace, fonts don't register these characters so # leaving them in here will break fontTools.subset cast_chars -= {c for c in string.whitespace} return subset.main(args=[ input_font, '--unicodes={}'.format(''.join(cast_chars).encode( "unicode-escape").decode("ascii").replace("\\u", "U+")), f'--output-file={output}', '--timing', ])
def test_recalc_max_context(self): ttxpath = self.getpath("Lobster.subset.ttx") font = TTFont() font.importXML(ttxpath) max_context = font['OS/2'].usMaxContext _, fontpath = self.compile_font(ttxpath, ".otf") subsetpath = self.temp_path(".otf") # by default, the subsetter does not recalculate the usMaxContext subset.main([fontpath, "--drop-tables+=GSUB,GPOS", "--output-file=%s" % subsetpath]) self.assertEqual(max_context, TTFont(subsetpath)['OS/2'].usMaxContext) subset.main([fontpath, "--recalc-max-context", "--drop-tables+=GSUB,GPOS", "--output-file=%s" % subsetpath]) self.assertEqual(0, TTFont(subsetpath)['OS/2'].usMaxContext)
def test_non_BMP_text_file_input(self): _, fontpath = self.compile_font( self.getpath("TestTTF-Regular_non_BMP_char.ttx"), ".ttf") subsetpath = self.temp_path(".ttf") text = tobytes(u"A\U0001F6D2", encoding='utf-8') with tempfile.NamedTemporaryFile(delete=False) as tmp: tmp.write(text) try: subset.main([fontpath, "--text-file=%s" % tmp.name, "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) finally: os.remove(tmp.name) self.assertEqual(subsetfont['maxp'].numGlyphs, 3) self.assertEqual(subsetfont.getGlyphOrder(), ['.notdef', 'A', 'u1F6D2'])
def test_subset_single_glyph_per_svg(empty_svg_font, add_svg_table, tmp_path, gids, retain_gids, expected_xml): font = add_svg_table(empty_svg_font) svg_font_path = tmp_path / "TestSVG.ttf" font.save(svg_font_path) subset_path = svg_font_path.with_suffix(".subset.ttf") subset.main([ str(svg_font_path), f"--output-file={subset_path}", f"--gids={gids}", "--retain_gids" if retain_gids else "--no-retain_gids", ]) subset_font = TTFont(subset_path) assert getXML(subset_font["SVG "].toXML, subset_font) == expected_xml
def test_subset_COLRv1_and_CPAL_drop_empty(colrv1_path): subset_path = colrv1_path.parent / (colrv1_path.name + ".subset") subset.main([ str(colrv1_path), "--glyph-names", f"--output-file={subset_path}", "--glyphs=glyph00010", ]) subset_font = TTFont(subset_path) glyph_set = set(subset_font.getGlyphOrder()) assert "glyph00010" in glyph_set assert "uniE000" not in glyph_set assert "COLR" not in subset_font assert "CPAL" not in subset_font
def test_recalc_bounds_otf(self): ttxpath = self.getpath("TestOTF-Regular.ttx") font = TTFont() font.importXML(ttxpath) head = font['head'] bounds = [head.xMin, head.yMin, head.xMax, head.yMax] _, fontpath = self.compile_font(ttxpath, ".otf") subsetpath = self.temp_path(".otf") # by default, the subsetter does not recalculate the bounding box subset.main([fontpath, "--output-file=%s" % subsetpath, "*"]) head = TTFont(subsetpath)['head'] self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax]) subset.main([fontpath, "--recalc-bounds", "--output-file=%s" % subsetpath, "*"]) head = TTFont(subsetpath)['head'] bounds = [132, 304, 365, 567] self.assertEqual(bounds, [head.xMin, head.yMin, head.xMax, head.yMax])
def execute_pyftsubset(self, pipedata, subsetname, name, glyphs="", args=""): from fontTools import subset argv = [op.join(self.builddir, name)] + glyphs.split() # argv += ['--notdef-outline', '--name-IDs="*"', '--hinting'] override_argv = [] if pipedata.get('pyftsubset'): override_argv = pipedata['pyftsubset'].split() if pipedata.get('pyftsubset.%s' % subsetname): override_argv = pipedata['pyftsubset.%s' % subsetname].split() argv = argv + override_argv subset.main(argv) self.bakery.logging_cmd('pyftsubset %s' % ' '.join(argv)) # need to move result .subset file to avoid overwrite with # next subset shutil.move(op.join(self.builddir, name) + '.subset', op.join(self.builddir, name)[:-4] + '.' + subsetname, log=self.bakery.log)
def test_passthrough_tables(self): _, fontpath = self.compile_font(self.getpath("TestTTF-Regular.ttx"), ".ttf") font = TTFont(fontpath) unknown_tag = 'ZZZZ' unknown_table = newTable(unknown_tag) unknown_table.data = b'\0'*10 font[unknown_tag] = unknown_table font.save(fontpath) subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) # tables we can't subset are dropped by default self.assertFalse(unknown_tag in subsetfont) subsetpath = self.temp_path(".ttf") subset.main([fontpath, "--passthrough-tables", "--output-file=%s" % subsetpath]) subsetfont = TTFont(subsetpath) # unknown tables are kept if --passthrough-tables option is passed self.assertTrue(unknown_tag in subsetfont)
def GET(self, name): #data = json.loads(web.data()) name = "fangzheng.TTF" data = "--text=我们" arg = [name,data] #fontTools.subset.main(arg) subset.main(arg) outputFile = "/tmp/" + name + ".subset" if (os.path.isfile(outputFile)): try: f = open(outputFile, "rb") web.header('Content-Type','application/octet-stream') web.header('Content-disposition','attachment; filename=%s.dat' % outputFile) while True: c = f.read(BUF_SIZE) if c: yield c else: break except Exception, e: yield e #yield 'Error when read font file' finally: