Skip to content

Instantly share code, notes, and snippets.

@m4rc1e
Created June 22, 2017 12:41
Show Gist options
  • Save m4rc1e/84da8ff0ff16678bfd840494eab4c3a0 to your computer and use it in GitHub Desktop.
Save m4rc1e/84da8ff0ff16678bfd840494eab4c3a0 to your computer and use it in GitHub Desktop.
import csv
import json
from fontTools.ttLib import TTFont
class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return json.JSONEncoder.default(self, obj)
def get_glyph_contours(font, glyph):
"""
Flatten a glyph's components and count each contour
"""
contour_count = 0
components = [glyph]
while components:
g = components.pop(0)
if g.isComposite():
for comp in g.components:
components.append(font['glyf'][comp.glyphName])
if g.numberOfContours != -1:
contour_count += g.numberOfContours
return contour_count
def get_font_data(font):
contour_map = []
cmap = font['cmap'].getcmap(3,1).cmap
cmap_reversed = dict(zip(cmap.values(), cmap.keys()))
for glyph_name in font.getGlyphSet().keys():
if glyph_name in cmap_reversed:
uni_glyph = cmap_reversed[glyph_name]
contours = get_glyph_contours(font, font['glyf'][glyph_name])
contour_map.append({
'unicode': uni_glyph,
'name': glyph_name,
'contours': set([contours])
})
return contour_map
def combine_fonts_data(fonts_data):
unnested_data = []
glyph_pos = {}
g_count = 0
for family in fonts_data:
for glyph in family:
if glyph['unicode'] not in glyph_pos:
glyph_pos[glyph['unicode']] = g_count
g_count += 1
unnested_data.append(glyph)
else:
unnested_contours = unnested_data[glyph_pos[glyph['unicode']]]['contours']
unnested_data[glyph_pos[glyph['unicode']]]['contours'] = unnested_contours | glyph['contours']
return unnested_data
def main():
fonts_path = [
'/Library/Fonts/Arial.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/prozalibre/ProzaLibre-SemiBoldItalic.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/sourceserifpro/SourceSerifPro-Bold.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/rosarivo/Rosarivo-Regular.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/rosarivo/Rosarivo-Italic.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/raleway/Raleway-BlackItalic.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/librebaskerville/LibreBaskerville-Bold.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/worksans/WorkSans-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ufl/ubuntu/Ubuntu-BoldItalic.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/vollkorn/Vollkorn-BlackItalic.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/breeserif/BreeSerif-Regular.ttf',
'/Users/marc/Documents/googlefonts/old_repo/old-googlefontdirectory/ofl/cantarell/Cantarell-Oblique.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/cantoraone/CantoraOne-Regular.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/carme/Carme-Regular.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/creteround/CreteRound-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/cuprum/Cuprum-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/eczar/Eczar-Bold.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/enriqueta/Enriqueta-Regular.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ofl/faunaone/FaunaOne-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/hind/Hind-Light.ttf',
'/Users/marc/Documents/googlefonts/hotfix/out/repo_cp/ufl/ubuntumono/UbuntuMono-Bold.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/belgrano/Belgrano-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/benchnine/BenchNine-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/trirong/Trirong-Light.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/archivonarrow/ArchivoNarrow-Bold.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/mitr/Mitr-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/overpass/Overpass-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/jura/Jura-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/overpass/Overpass-Black.ttf',
'/Users/marc/Documents/googlefonts/fonts/apache/roboto/Roboto-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/montserrat/Montserrat-Regular.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/montserrat/Montserrat-Black.ttf',
'/Users/marc/Documents/googlefonts/fonts/ofl/montserrat/Montserrat-Thin.ttf',
'/Users/marc/Documents/googlefonts/manual_font_cleaning/20160628-gfnt/99 prepublic/fonts/desktop/Spectral-Regular.ttf',
]
fonts_data = []
for font_path in fonts_path:
font = TTFont(font_path)
fonts_data.append(get_font_data(font))
m_data = combine_fonts_data(fonts_data)
with open('glyph_data.json', 'w') as glyph_file:
json.dump(m_data, glyph_file, indent=4, cls=SetEncoder)
print 'done'
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment