Skip to content

Commit

Permalink
only build minimal metrics/outline tables for sparse layer masters
Browse files Browse the repository at this point in the history
Fixes googlefonts#308

The OutlineCompiler classes gets a tables keyword argument that allows to
customize the list of tables to be built.
For the interpolatable sparse masters (those built from non-default layer)
we only build (head, maxp, {h,v}mtx, loca, glyf, and post) for TTF, and
(head, maxp, CFF, {h,v}mtx and VORG) for CFF-OTF.

NOTE that varLib still doesn't support vmtx or VORG, but we output them
anyway.
  • Loading branch information
anthrotype committed Jan 16, 2019
1 parent e01ffc3 commit 8f2a242
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 50 deletions.
31 changes: 24 additions & 7 deletions Lib/ufo2ft/__init__.py
Expand Up @@ -17,6 +17,7 @@
)
from ufo2ft.outlineCompiler import OutlineOTFCompiler, OutlineTTFCompiler
from ufo2ft.postProcessor import PostProcessor
from ufo2ft.constants import SPARSE_TTF_MASTER_TABLES, SPARSE_OTF_MASTER_TABLES
import logging

try:
Expand Down Expand Up @@ -48,6 +49,7 @@ def compileOTF(
overlapsBackend=None,
inplace=False,
layerName=None,
_tables=None,
):
"""Create FontTools CFF font from a UFO.
Expand Down Expand Up @@ -81,9 +83,8 @@ def compileOTF(
**inplace** (bool) specifies whether the filters should modify the input
UFO's glyphs, a copy should be made first.
*layerName* specifies which layer should be compiled. Useful for generating
sparse masters. When compiling something other than the default layer,
feature compilation is skipped.
*layerName* specifies which layer should be compiled. When compiling something
other than the default layer, feature compilation is skipped.
"""
logger.info("Pre-processing glyphs")
preProcessor = preProcessorClass(
Expand All @@ -103,6 +104,7 @@ def compileOTF(
glyphOrder=glyphOrder,
roundTolerance=roundTolerance,
optimizeCFF=optimizeCFF >= CFFOptimization.SPECIALIZE,
tables=_tables,
)
otf = outlineCompiler.compile()

Expand Down Expand Up @@ -149,9 +151,8 @@ def compileTTF(
*convertCubics* and *cubicConversionError* specify how the conversion from cubic
to quadratic curves should be handled.
*layerName* specifies which layer should be compiled. Useful for generating
sparse masters. When compiling something other than the default layer,
feature compilation is skipped.
*layerName* specifies which layer should be compiled. When compiling something
other than the default layer, feature compilation is skipped.
"""
logger.info("Pre-processing glyphs")
preProcessor = preProcessorClass(
Expand Down Expand Up @@ -211,6 +212,10 @@ def compileInterpolatableTTFs(
*layerNames* refers to the layer names to use glyphs from in the order of
the UFOs in *ufos*. By default, this is a list of `[None]` times the number
of UFOs, i.e. using the default layer from all the UFOs.
When the layerName is not None for a given UFO, the corresponding TTFont object
will contain only a minimum set of tables ("head", "hmtx", "glyf", "loca", "maxp",
"post" and "vmtx"), and no OpenType layout tables.
"""
from ufo2ft.util import _LazyFontName

Expand All @@ -232,7 +237,10 @@ def compileInterpolatableTTFs(
logger.info("Building OpenType tables for %s", _LazyFontName(ufo))

outlineCompiler = outlineCompilerClass(
ufo, glyphSet=glyphSet, glyphOrder=glyphOrder
ufo,
glyphSet=glyphSet,
glyphOrder=glyphOrder,
tables=SPARSE_TTF_MASTER_TABLES if layerName else None,
)
ttf = outlineCompiler.compile()

Expand Down Expand Up @@ -277,6 +285,10 @@ def compileInterpolatableTTFsFromDS(
Return a copy of the DesignSpaceDocument object (or the same one if
inplace=True) with the source's 'font' attribute set to the corresponding
TTFont instance.
For sources that have the 'layerName' attribute defined, the corresponding TTFont
object will contain only a minimum set of tables ("head", "hmtx", "glyf", "loca",
"maxp", "post" and "vmtx"), and no OpenType layout tables.
"""
ufos, layerNames = [], []
for source in designSpaceDoc.sources:
Expand Down Expand Up @@ -338,6 +350,10 @@ def compileInterpolatableOTFsFromDS(
Return a copy of the DesignSpaceDocument object (or the same one if
inplace=True) with the source's 'font' attribute set to the corresponding
TTFont instance.
For sources that have the 'layerName' attribute defined, the corresponding TTFont
object will contain only a minimum set of tables ("head", "hmtx", "CFF ", "maxp",
"vmtx" and "VORG"), and no OpenType layout tables.
"""
for source in designSpaceDoc.sources:
if source.font is None:
Expand All @@ -363,6 +379,7 @@ def compileInterpolatableOTFsFromDS(
removeOverlaps=False,
overlapsBackend=None,
inplace=inplace,
_tables=SPARSE_OTF_MASTER_TABLES if source.layerName else None,
)
)

Expand Down
8 changes: 6 additions & 2 deletions Lib/ufo2ft/constants.py
@@ -1,8 +1,12 @@
from __future__ import absolute_import, unicode_literals

SPARSE_TTF_MASTER_TABLES = frozenset(
["glyf", "head", "hmtx", "loca", "maxp", "post", "vmtx"]
)
SPARSE_OTF_MASTER_TABLES = frozenset(["CFF ", "VORG", "head", "hmtx", "maxp", "vmtx"])

UFO2FT_PREFIX = 'com.github.googlei18n.ufo2ft.'
GLYPHS_PREFIX = 'com.schriftgestaltung.'
UFO2FT_PREFIX = "com.github.googlei18n.ufo2ft."
GLYPHS_PREFIX = "com.schriftgestaltung."

USE_PRODUCTION_NAMES = UFO2FT_PREFIX + "useProductionNames"
GLYPHS_DONT_USE_PRODUCTION_NAMES = GLYPHS_PREFIX + "Don't use Production Names"

0 comments on commit 8f2a242

Please sign in to comment.