summaryrefslogtreecommitdiff
path: root/fonttools/fonttools_slides.py
diff options
context:
space:
mode:
Diffstat (limited to 'fonttools/fonttools_slides.py')
-rwxr-xr-xfonttools/fonttools_slides.py424
1 files changed, 344 insertions, 80 deletions
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 &amp;\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+ &amp; 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 &amp; 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