1
0
mirror of https://github.com/google/fonts.git synced 2024-12-13 05:32:35 +03:00
fonts/tools/space_check.py

108 lines
2.7 KiB
Python
Raw Normal View History

2016-01-04 23:17:45 +03:00
import contextlib
import os
from fontTools import ttLib
from google.apputils import app
from util import google_fonts as fonts
def _LoadGlyf(font, char, name, problems):
"""Loads a glyf and expands (populates fields) it.
Args:
font: A TTFont.
char: int id of char, e.g. ord('C').
name: name to use in problems string describing char. e.g. SPACE.
problems: set to add problems to.
Returns:
2-tuple of (cmap_key, glyph). (None, None) if a problem occurred. Adds
to problems if a problem occurred.
"""
if 'glyf' not in font:
problems.add('NO_GLYF_TABLE')
return (None, None)
cmap = fonts.UnicodeCmapTables(font).next().cmap
if char not in cmap:
problems.add('NO_%s' % name)
return (None, None)
key = cmap[char]
glyph = font['glyf'].glyphs[key]
glyph.expand(font['glyf'])
return (key, glyph)
def _HasInk(font, glyph_name):
"""Checks if specified glyph has any ink.
That is, that it has at least one defined contour associated. Composites are
considered to have ink if any of their components have ink.
Args:
font: A TTFont that has a 'glyf' table.
glyph_name: The name of the glyph to check for ink.
Returns:
True if the font has at least one contour associated with it.
"""
glyph = font['glyf'].glyphs[glyph_name]
glyph.expand(font['glyf'])
if not glyph.isComposite():
if glyph.numberOfContours == 0:
return False
(coords, _, _) = glyph.getCoordinates(font['glyf'])
# you need at least 3 points to draw
return len(coords) > 2
# composite is blank if composed of blanks
# if you setup a font with cycles you are just a bad person
for glyph_name in glyph.getComponentNames(glyph.components):
if _HasInk(font, glyph_name):
return True
return False
def _CheckFont(font):
"""Inspects a font for space/nbsp issues.
Args:
font: A TTFont.
Returns:
A set of strings describing problems found in the font. Empty set if none.
"""
problems = set()
(space_cmap, _) = _LoadGlyf(font, 0x0020, 'SPACE', problems)
(nbsp_cmap, _) = _LoadGlyf(font, 0x00A0, 'NBSP', problems)
if nbsp_cmap and _HasInk(font, nbsp_cmap):
problems.add('NBSP_HAS_INK')
if space_cmap and _HasInk(font, space_cmap):
problems.add('SPACE_HAS_INK')
if nbsp_cmap and space_cmap:
if font['hmtx'][nbsp_cmap][0] != font['hmtx'][space_cmap][0]:
problems.add('SPACE_NBSP_WIDTH_MISMATCH')
return set(problems)
def main(argv):
for filename in argv[1:]:
with contextlib.closing(ttLib.TTFont(filename)) as font:
problems = _CheckFont(font)
if not problems:
problems.add('OK')
print '{:48} {}'.format(os.path.basename(filename),
','.join(sorted(problems)))
if __name__ == '__main__':
app.run()