diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2014-09-17 08:30:55 +0200 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2014-09-17 08:30:55 +0200 |
commit | d88c6d90f2537a602c34f3b21c9f97ab9a20196d (patch) | |
tree | ac94ff04bc70c2bcfe9f1b7e35da4baf822392e4 | |
parent | 155410efbd93813e8f444f6b9eaf31917159cc28 (diff) |
[fonttools] Flesh out
-rw-r--r-- | fonttools/behdad.png | bin | 11176 -> 80676 bytes | |||
-rwxr-xr-x | fonttools/fonttools_slides.py | 424 | ||||
-rw-r--r-- | fonttools/fonttools_theme.py | 6 | ||||
-rw-r--r-- | fonttools/snippets/drop_glyphnames.py | 8 | ||||
-rw-r--r-- | fonttools/snippets/merging.txt | 11 | ||||
-rw-r--r-- | fonttools/snippets/rename_glyphs.py | 12 | ||||
-rw-r--r-- | fonttools/snippets/subsetting.txt | 32 | ||||
-rw-r--r-- | fonttools/snippets/tofu.ttx | 16 | ||||
-rw-r--r-- | fonttools/snippets/ttx.ttx | 204 | ||||
-rw-r--r-- | fonttools/snippets/unencoded.py | 12 | ||||
-rw-r--r-- | pangopygments.py | 9 | ||||
-rwxr-xr-x | slippy.py | 1 |
12 files changed, 648 insertions, 87 deletions
diff --git a/fonttools/behdad.png b/fonttools/behdad.png Binary files differindex b9ed80f..7a07e71 100644 --- a/fonttools/behdad.png +++ b/fonttools/behdad.png diff --git a/fonttools/fonttools_slides.py b/fonttools/fonttools_slides.py index a95d6de..1bebe92 100755 --- a/fonttools/fonttools_slides.py +++ b/fonttools/fonttools_slides.py @@ -23,9 +23,16 @@ # The more useful of them here are put_text, put_image, and # set_allocation. See their pydocs. +title_font="Cinzel" +head_font="Julius Sans One Bold" +body_font="Merriweather Sans Light" + slides = [] def slide_add(f, data=None, width=800, height=600): - #slides[:0] = [(f, data, width, height)] + if data is None: + data = {} + if "desc" not in data: + data['desc'] = body_font slides.append ((f, data, width, height)) return f @@ -39,6 +46,7 @@ whois = 0 def who(name): global whois whois = name + # And convenience functions to add a slide. Can be # used as a function decorator, or called directly. def slide_who(f, who, data=None): @@ -48,45 +56,28 @@ def slide_who(f, who, data=None): data = {} data['who'] = who return slide_add (f, data) + def slide(f, data=None): return slide_who (f, whois, data=data) -def slide_noone(f, data=None): + +def slide_heading(f, data=None): + if data is None: + data = {} + if 'desc' not in data: + data['desc'] = head_font if data and 'who' in data: return slide_who (f, data['who'], data=data) else: return slide_who (f, 0, data=data) -# -# Slides start here -# - -who (behdad) - -@slide -def title_slide (r): - r.move_to (400, 250) - r.put_text ("<b>FontTools</b>\n"+ - "<span font_desc='30'>"+ - "reviving an Open Source project &\n"+ - "<span strikethrough='true'>re</span>building a thriving community"+ - "</span>", valign=0, halign=0, desc="100") - - r.move_to (400, 550) - r.put_text ("""Behdad Esfahbod\n<span font_desc="monospace 16">behdad@google.com\nhttp://behdad.org</span>""", - desc="20", halign=0, valign=-1) - -def list_slide (l, data=None): +def bullet_list_slide (title, items): def s (r): - return '\n'.join (l) - #yield l[0] - #for i in l[1:]: - # yield '\n'+i - s.__name__ = l[0] + ts = "<span font_desc='"+head_font+"'>"+title+"</span>\n" + return ts + '\n'.join ("• " + item for item in items) + s.__name__ = title + data={'desc': body_font, 'align': pango.ALIGN_LEFT} slide (s, data) -slide_noone("History") -slide_noone("Where") - def image_slide (f, width=600, height=600, imgwidth=0, imgheight=0, xoffset=0, yoffset=0, data=None): def s (r): r.move_to (400+xoffset, 300+yoffset) @@ -105,33 +96,16 @@ def draw_image (r, f, width=600, height=600, imgwidth=0, imgheight=0, xoffset=0, y = (600 - height) * .5 r.set_allocation (x, y, width, height) -slide_noone("<b>Demo\ntime!</b>") - -# Demo! - -slide_noone("<b>Limitations</b>") -slide("Memory\nfootprint") -slide("Speed+memory\nfont-dependent") - -slide_noone("<b>Advantages</b>") -slide("Memory\nfootprint") -slide("Subpixel\npositioning") -slide("Pinch-to-zoom") - -list_slide ([ - "<b>Challenges</b>", - "• Shader size / complexity", - "• Pixel cost", - "• Conditionals", - "• Dependent texture lookups", - "• Variable loop iterations", - "• Interpolation accuracy", - ], data={'align': pango.ALIGN_LEFT}) - -def source_slide(s, lang="python"): +def source_slide(s, lang): s = highlight(s, lang) s = "<span font_desc='monospace'>" + s + "</span>" - slide_noone (s, data={'align': pango.ALIGN_LEFT}) + slide_heading (s, data={'align': pango.ALIGN_LEFT}) + +def python_slide(s): + source_slide(s, lang="py") + +def xml_slide(s): + source_slide(s, lang="xml") def patch_slide(s): lines = s.split ("\n") @@ -150,7 +124,7 @@ def patch_slide(s): s = '\n'.join (new_lines) s = "<span font_desc='monospace'>" + s + "</span>" - slide_noone (s, data={'align': pango.ALIGN_LEFT}) + slide_heading (s, data={'align': pango.ALIGN_LEFT}) def commit_slide(s, who=None): lines = s.split ("\n") @@ -166,31 +140,321 @@ def commit_slide(s, who=None): s = '\n'.join (new_lines) s = "<span font_desc='monospace'>" + s + "</span>" if who: - slide_noone (s, data={'align': pango.ALIGN_LEFT, 'who': who}) + slide_heading (s, data={'align': pango.ALIGN_LEFT, 'who': who}) else: - slide_noone (s, data={'align': pango.ALIGN_LEFT}) - -list_slide ([ - "<b>Code: libglyphy</b>", - "• ~400 lines *.h", - "• ~2500 lines *.cc *.hh", - "• ~370 lines *.glsl", - "• No dependencies", - ], data={'align': pango.ALIGN_LEFT}) -list_slide ([ - "<b>Code: glyphy-demo</b>", - "• ~2800 lines *.cc *.h", - "• ~150 lines *.glsl", - "• FreeType, GLUT", - ], data={'align': pango.ALIGN_LEFT}) -list_slide ([ - "<b>More work</b>", - "• Subpixel-rendering", - "• Anisotropic-antialiasing", - ], data={'align': pango.ALIGN_LEFT}) - -slide("<b>Gallery!</b>") -slide("<b>Q?</b>") + slide_heading (s, data={'align': pango.ALIGN_LEFT}) + + +# +# Slides start here +# + +who (behdad) + +@slide +def title_slide (r): + r.move_to (400, 250) + r.put_text ("<span font_desc='"+title_font+" bold'>FontTools</span>\n"+ + "<span font_desc='"+head_font+" 30'>"+ + "reviving an Open Source project,\n"+ + "<span strikethrough='true'>re</span>building a thriving community"+ + "</span>", valign=0, halign=0, desc=title_font+" 100") + + r.move_to (400, 550) + r.put_text ("""Behdad Esfahbod""", desc=body_font+" 20", halign=0, valign=-1) + +bullet_list_slide("History", [ + "Started in 1999ish", + "by Just van Rossum", + "of LettError fame", + "Slowed down by 2004", + "I picked it up last year"]) +bullet_list_slide("What is it?", [ + "Two things: TTX and fontTools", + "TTX converts fonts to XML and back", + "fontTools is a Python library", + "Font engineer's calculator", + "Closely reflecting OpenType tables", + "Minimum abstractions"]) + +slide_heading("TTX") +xml_slide(""" +<?xml version="1.0" encoding="utf-8"?> +<ttFont sfntVersion="\\x00\\x01\\x00\\x00" ttLibVersion="2.5"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="T"/> + <GlyphID id="2" name="X"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.001"/> + <checkSumAdjustment value="0x22ff1f02"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00001011"/> + <unitsPerEm value="1000"/> + ... + </head> + + <hhea> + <tableVersion value="1.0"/> + <ascent value="863"/> + <descent value="-228"/> + <lineGap value="0"/> + ... + </hhea> +""") +xml_slide(""" + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="3"/> + <maxPoints value="68"/> + <maxContours value="7"/> + ... + </maxp> + + <OS_2> + <version value="3"/> + <xAvgCharWidth value="560"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000000"/> + ... + </OS_2> +""") +xml_slide(""" + <hmtx> + <mtx name=".notdef" width="260" lsb="0"/> + <mtx name="T" width="576" lsb="22"/> + <mtx name="X" width="584" lsb="26"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="3" platEncID="1" language="0"> + <map code="0x54" name="T"/><!-- LATIN CAPITAL LETTER T --> + <map code="0x58" name="X"/><!-- LATIN CAPITAL LETTER X --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> +""") +xml_slide(""" + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="T" xMin="22" yMin="0" xMax="554" yMax="715"> + <contour> + <pt x="264" y="673" on="1"/> + <pt x="22" y="673" on="1"/> + <pt x="22" y="715" on="1"/> + <pt x="554" y="715" on="1"/> + <pt x="554" y="673" on="1"/> + <pt x="312" y="673" on="1"/> + <pt x="312" y="0" on="1"/> + <pt x="264" y="0" on="1"/> + </contour> + <instructions><assembly> + </assembly></instructions> + </TTGlyph> + + <TTGlyph name="X" xMin="26" yMin="0" xMax="558" yMax="715"> + ... + </TTGlyph> + + </glyf> +""") +xml_slide(""" + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Julius Sans One + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="-75"/> + <underlineThickness value="50"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + +</ttFont> +""") + +slide_heading("fontTools") +bullet_list_slide("<span font_desc='monospace' foreground='#080'>from <span foreground='#00f'><b>fontTools</b></span> import</span>", [ + "afmLib", + "cffLib", + "<span strikethrough='true'>fondLib</span>", + "<span strikethrough='true'>nfntLib</span>", + "t1Lib", + "<b>ttLib</b>", + ]) +python_slide(open("snippets/unencoded.py").read()) +python_slide(""" +set(['A.salt', + 'B.salt', + 'E.salt', + 'E_x', + 'F_i', + 'N.salt', + 'NULL', + 'T_h', + 'T_i', + 'a.end', + ... + 'y_z']) +""") + +bullet_list_slide("Framework", [ + "Compiler / decompiler", + "XML serialization", + "Optimizer", + "Library", + "A tool to build products with", + "Not an end product", +]) +bullet_list_slide("Philosophy", [ + "Minimal abstraction", + "Hide byte layout, redundancy, etc", + "Platform to build on", +]) +bullet_list_slide("Why?", [ + "Free Software", + "Python (2.7+ & 3.x)", + "Portable", + "No dependencies", + "Non-destructive", + "Batch-friendly", +]) +bullet_list_slide("What for?", [ + "Figuring out what's inside a font", + "Diff'ing font versions", + "Final steps of producing fonts", + "Hotfixing existing fonts", + "Reporting and analysis over <i>many</i> fonts", + "Server-side reporting and manipulation", + "Readable VCS-friendly font source code", + "Subsetting and merging fonts", +]) +bullet_list_slide("Hotfixing", [ + "XML and back", + "Python recipes", + "Interactive Python", +]) +python_slide(open("snippets/drop_glyphnames.py").read()) +python_slide(open("snippets/rename_glyphs.py").read()) + +bullet_list_slide("New work", [ + "Bitmap tables, color tables, misc tables", + "WOFF1 read and write", + "More stable XML format", + "More optimized font files", + "Bug fixes; many of them", + "Major speed-up", + "New tools", +]) + +bullet_list_slide("Tools", [ + "pyftsubset", + "pyftmerge", + "pyftinspect", +]) +bullet_list_slide("pyftsubset", [ + "OpenType font subsetter & optimizer", + "TrueType and CFF flavored", + "SFNT and WOFF1", + "Full OpenType Layout support", + "File-size optimizations", + "Designed for webfont productions", + "Used for sub-family instantiation", +]) +source_slide(open("snippets/subsetting.txt").read(), "text") +bullet_list_slide("pyftmerge", [ + "Font merging tool", + "Very early prototype", + "Fonts having same format, upem", + "TrueType-flavored only", + "Retains hinting from one font", + "Handles conflicting characters", + "Designed for Noto", + "Used for merging Latin and non-Latin", +]) +source_slide(open("snippets/merging.txt").read(), "text") + +# 1. Feel free to mention in your talk Yannis Haralambous' book "Fonts & Encodings" [1], simply because it can be seen as a "user manual for TTX". It talks extensively about the various SFNT tables, and illustrates them using TTX XML structures. So, while fontTools itself has very lacking documentation*, the book is actually a great companion. When I read the book and I look at the .ttx XML representation of a font, I have good chances to actually understand how it all works. + +slide_heading("FontTools") +bullet_list_slide("Strengths", [ + "Supports wide array of tables", + "Low-level, non-destructive", + "Python", + "Self-documenting", + "Optimized output", + "Extensible", + "Supports all color tables", +]) +bullet_list_slide("Weaknesses", [ + "Supports wide array of tables", + "Low-level, non-destructive", + "Python", + "Undocumented", + "Always optimizes output", + "Not well-extensible", + "Supports many legacy tables", +]) +bullet_list_slide("Users", [ + "Google Fonts; misc foundries", + "Font Bakery, AFDKO, etc", + "Adam Twardoch; others", + "...", +]) +bullet_list_slide("Community", [ + "https://github.com/behdad/fonttools/", + "https://groups.google.com/forum/#!forum/fonttools", + "http://sourceforge.net/projects/fonttools/", +]) + +bullet_list_slide("Future work", [ + "More font optimization", + "Better input: .fea / UFO", + "Lint tool", + "TrueType / CFF conversion", + "Subsetting more tables", + "Better merging", +]) +bullet_list_slide("Future work: optimization", [ + "Optimal packing: glyf flags / PUSH / etc", + "CFF outline operation specializer", + "CFF subroutinizer", + "TrueType outline optimizer? (fontcrunch)", + "TrueType bytecode analysis", + "UPEM reduction", +]) + +slide("<b>Q?</b>", data={"desc":title_font}) +python_slide('') + +xml_slide(open("snippets/tofu.ttx").read()) if __name__ == "__main__": import slippy diff --git a/fonttools/fonttools_theme.py b/fonttools/fonttools_theme.py index 5c5bbf3..078c9de 100644 --- a/fonttools/fonttools_theme.py +++ b/fonttools/fonttools_theme.py @@ -20,7 +20,7 @@ import cairo avatar_margin = .10 logo_margin = .01 -footer_margin = .04 +footer_margin = .05 padding = .000 bubble_rad = .25 @@ -76,7 +76,7 @@ def prepare_page (renderer): cr.move_to (.5 * width, height-p2) b = 150. cr.set_source_rgb (0x9b/b, 0x84/b, 0x66/b) - renderer.put_text ("ATypI Barcelona, 17 September 2014", height=f-p2, valign=-1, desc="bold") + renderer.put_text ("ATypI Barcelona, 17 September 2014", height=f-p2, valign=-1, desc="cinzel") # Cartoon icons for speakers who = renderer.data.get ('who', None) @@ -135,7 +135,7 @@ def draw_bubble (renderer, x, y, w, h, data={}): cr.restore () cr.clip () - cr.set_source_rgba (1, 1, 1, .95) + cr.set_source_rgba (1, 1, 1, .94) cr.paint () b = 700. diff --git a/fonttools/snippets/drop_glyphnames.py b/fonttools/snippets/drop_glyphnames.py new file mode 100644 index 0000000..46fcb99 --- /dev/null +++ b/fonttools/snippets/drop_glyphnames.py @@ -0,0 +1,8 @@ +import fontTools.ttLib + +font = fontTools.ttLib.TTFont(inpath) +post = font['post'] + +post.fomratType = 3.0 + +font.save(outpath) diff --git a/fonttools/snippets/merging.txt b/fonttools/snippets/merging.txt new file mode 100644 index 0000000..20426b8 --- /dev/null +++ b/fonttools/snippets/merging.txt @@ -0,0 +1,11 @@ +$ pyftmerge NotoSansDevanagari-Regular.ttf NotoSansBengali-Regular.ttf +$ ls -l +-rw-r--r-- 1 behdad eng 266580 Sep 17 08:19 merged.ttf +-rw-r--r-- 1 behdad eng 188664 Sep 17 08:18 NotoSansBengali-Regular.ttf +-rw-r--r-- 1 behdad eng 177672 Sep 17 08:18 NotoSansDevanagari-Regular.ttf + +$ pyftmerge NotoSansBengali-Regular.ttf NotoSansDevanagari-Regular.ttf +$ ls -l +-rw-r--r-- 1 behdad eng 293276 Sep 17 08:21 merged.ttf +-rw-r--r-- 1 behdad eng 188664 Sep 17 08:18 NotoSansBengali-Regular.ttf +-rw-r--r-- 1 behdad eng 177672 Sep 17 08:18 NotoSansDevanagari-Regular.ttf diff --git a/fonttools/snippets/rename_glyphs.py b/fonttools/snippets/rename_glyphs.py new file mode 100644 index 0000000..2c88a74 --- /dev/null +++ b/fonttools/snippets/rename_glyphs.py @@ -0,0 +1,12 @@ +import fontTools.ttLib + +font = fontTools.ttLib.TTFont(inpath) +glyphnames = font.getGlyphOrder() + +# ...do the actual renaming in glyphnames... + +font = fontTools.ttLib.TTFont(inpath) # load again +font.setGlyphOrder(glyphnames) +post = font['post'] # make sure post table is loaded + +font.save(outpath) diff --git a/fonttools/snippets/subsetting.txt b/fonttools/snippets/subsetting.txt new file mode 100644 index 0000000..767c238 --- /dev/null +++ b/fonttools/snippets/subsetting.txt @@ -0,0 +1,32 @@ +$ pyftsubset Lobster.ttf --text=Lobster --glyph-names --verbose +Text: 'Lobster' +Unicodes: [] +Glyphs: [] +Gids: [] +cmap pruned +glyf pruned +... +Added gid0 to subset +Closing glyph list over 'GSUB': 8 glyphs before +Glyph names: ['.notdef', 'L', 'b', 'e', 'o', 'r', 's', 't'] +Closed glyph list over 'GSUB': 16 glyphs after +Glyph names: ['.notdef', 'L', 'b', 'b_s', 'b_s.end', 'e', 'e.end', 'o', + 'o.end', 'o_s', 'o_s.end', 'r', 's', 's.end', 't', 't.end'] +Retaining 16 glyphs: +head subsetting not needed +... +hmtx subsetted +cmap subsetted +glyf subsetted +kern subsetted to empty; dropped +name subsetting not needed +GDEF subsetted +GPOS subsetted +GSUB subsetted +... +glyf pruned +GDEF pruned +GPOS pruned +GSUB pruned +Input font: 140856 bytes: Lobster.ttf +Subset font: 4648 bytes: Lobster.ttf.subset diff --git a/fonttools/snippets/tofu.ttx b/fonttools/snippets/tofu.ttx new file mode 100644 index 0000000..f94f414 --- /dev/null +++ b/fonttools/snippets/tofu.ttx @@ -0,0 +1,16 @@ + <cmap raw="1"> + <!-- Hand-coded format13 table mapping all Unicode + characters to glyph00001. --> + <hexdata> + 0000 0001 <!-- version numTables --> + 0003 000A <!-- platformID encodingID --> + 0000000C <!-- offset --> + 000D 0000 <!-- format reserved --> + 0000001C <!-- length --> + 00000000 <!-- language --> + 00000001 <!-- nGroups --> + 00000001 <!-- startCharCode --> + 0010FFFE <!-- endCharCode --> + 00000001 <!-- glyphID --> + </hexdata> + </cmap> diff --git a/fonttools/snippets/ttx.ttx b/fonttools/snippets/ttx.ttx new file mode 100644 index 0000000..0c7520a --- /dev/null +++ b/fonttools/snippets/ttx.ttx @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="utf-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="2.5"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="T"/> + <GlyphID id="2" name="X"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.001"/> + <checkSumAdjustment value="0x22ff1f02"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00001011"/> + <unitsPerEm value="1000"/> + <created value="Sat Oct 6 04:04:08 2012"/> + <modified value="Sat Oct 6 04:04:08 2012"/> + <xMin value="-44"/> + <yMin value="-228"/> + <xMax value="1469"/> + <yMax value="863"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="8"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="1.0"/> + <ascent value="863"/> + <descent value="-228"/> + <lineGap value="0"/> + <advanceWidthMax value="1059"/> + <minLeftSideBearing value="-44"/> + <minRightSideBearing value="-586"/> + <xMaxExtent value="1469"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="3"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="3"/> + <maxPoints value="68"/> + <maxContours value="7"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="2"/> + <maxTwilightPoints value="0"/> + <maxStorage value="1"/> + <maxFunctionDefs value="1"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="64"/> + <maxSizeOfInstructions value="0"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <version value="3"/> + <xAvgCharWidth value="560"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000000"/> + <ySubscriptXSize value="650"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="650"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="350"/> + <yStrikeoutSize value="50"/> + <yStrikeoutPosition value="298"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="2"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="10000000 00000000 00000000 00101111"/> + <ulUnicodeRange2 value="01000000 00000000 00000000 01001010"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="T26\x00"/> + <fsSelection value="00000000 01000000"/> + <fsFirstCharIndex value="32"/> + <fsLastCharIndex value="64258"/> + <sTypoAscender value="863"/> + <sTypoDescender value="-228"/> + <sTypoLineGap value="0"/> + <usWinAscent value="863"/> + <usWinDescent value="228"/> + <ulCodePageRange1 value="00100000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="649"/> + <sCapHeight value="715"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContex value="2"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="260" lsb="0"/> + <mtx name="T" width="576" lsb="22"/> + <mtx name="X" width="584" lsb="26"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="3" platEncID="1" language="0"> + <map code="0x54" name="T"/><!-- LATIN CAPITAL LETTER T --> + <map code="0x58" name="X"/><!-- LATIN CAPITAL LETTER X --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="T" xMin="22" yMin="0" xMax="554" yMax="715"> + <contour> + <pt x="264" y="673" on="1"/> + <pt x="22" y="673" on="1"/> + <pt x="22" y="715" on="1"/> + <pt x="554" y="715" on="1"/> + <pt x="554" y="673" on="1"/> + <pt x="312" y="673" on="1"/> + <pt x="312" y="0" on="1"/> + <pt x="264" y="0" on="1"/> + </contour> + <instructions><assembly> + </assembly></instructions> + </TTGlyph> + + <TTGlyph name="X" xMin="26" yMin="0" xMax="558" yMax="715"> + <contour> + <pt x="53" y="715" on="1"/> + <pt x="112" y="715" on="1"/> + <pt x="304" y="401" on="1"/> + <pt x="504" y="715" on="1"/> + <pt x="557" y="715" on="1"/> + <pt x="327" y="364" on="1"/> + <pt x="558" y="0" on="1"/> + <pt x="500" y="0" on="1"/> + <pt x="294" y="332" on="1"/> + <pt x="79" y="0" on="1"/> + <pt x="26" y="0" on="1"/> + <pt x="270" y="370" on="1"/> + </contour> + <instructions><assembly> + </assembly></instructions> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Julius Sans One + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="-75"/> + <underlineThickness value="50"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + +</ttFont> diff --git a/fonttools/snippets/unencoded.py b/fonttools/snippets/unencoded.py new file mode 100644 index 0000000..a2c678e --- /dev/null +++ b/fonttools/snippets/unencoded.py @@ -0,0 +1,12 @@ +import fontTools.ttLib + +font = fontTools.ttLib.TTFont("Lobster.ttf") +cmap = font['cmap'] + +encoded = set() +for subtable in cmap.tables: + encoded.update(subtable.cmap.values()) +unencoded = set(font.getGlyphOrder()).difference(encoded) + +import pprint +pprint.pprint(unencoded) diff --git a/pangopygments.py b/pangopygments.py index 413f629..b9823c9 100644 --- a/pangopygments.py +++ b/pangopygments.py @@ -70,6 +70,7 @@ __LEXERS = { 'py': lexers.PythonLexer, 'scala': lexers.ScalaLexer, 'glsl': lexers.GLShaderLexer, + 'xml': lexers.XmlLexer, } def highlight(snippet, lang): @@ -81,11 +82,11 @@ def highlight(snippet, lang): # Pygments messes up initial and final newlines; fix up begin = '' - if snippet[0] == '\n': + if snippet[:1] == '\n': begin = '\n' snippet = snippet[1:] end = '' - if snippet[-1] == '\n': + if snippet[-1:] == '\n': end = '\n' snippet = snippet[:-1] @@ -94,8 +95,8 @@ def highlight(snippet, lang): else: print("Language %s is not supported." % lang) - if snippet[0] == '\n' and start == '\n': - start = '' + if snippet[0] == '\n' and begin == '\n': + begin = '' if snippet[-1] == '\n' and end == '\n': end = '' @@ -441,6 +441,7 @@ class Slide: layout = renderer.create_layout (self.text) layout.set_alignment (self.data.get ('align', pango.ALIGN_CENTER)) + layout.set_font_description (pango.FontDescription(self.data.get ('desc', "Sans"))) lw, lh = renderer.fit_layout (layout, w, h) ext = self.extents |