Skip to content

Commit

Permalink
Merge pull request #438 from simoncozens/flatten-components-option
Browse files Browse the repository at this point in the history
Flatten components option
  • Loading branch information
anthrotype authored Dec 10, 2020
2 parents a1803f3 + b0c9673 commit c12bac8
Show file tree
Hide file tree
Showing 27 changed files with 1,201 additions and 3 deletions.
11 changes: 11 additions & 0 deletions Lib/ufo2ft/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def compileTTF(
rememberCurveType=True,
removeOverlaps=False,
overlapsBackend=None,
flattenComponents=False,
inplace=False,
layerName=None,
skipExportGlyphs=None,
Expand All @@ -182,6 +183,9 @@ def compileTTF(
*removeOverlaps* performs a union operation on all the glyphs' contours.
*flattenComponents* un-nests glyphs so that they have at most one level of
components.
*convertCubics* and *cubicConversionError* specify how the conversion from cubic
to quadratic curves should be handled.
Expand All @@ -205,6 +209,7 @@ def compileTTF(
inplace=inplace,
removeOverlaps=removeOverlaps,
overlapsBackend=overlapsBackend,
flattenComponents=flattenComponents,
convertCubics=convertCubics,
conversionError=cubicConversionError,
reverseDirection=reverseDirection,
Expand Down Expand Up @@ -247,6 +252,7 @@ def compileInterpolatableTTFs(
useProductionNames=None,
cubicConversionError=None,
reverseDirection=True,
flattenComponents=False,
inplace=False,
layerNames=None,
skipExportGlyphs=None,
Expand Down Expand Up @@ -290,6 +296,7 @@ def compileInterpolatableTTFs(
ufos,
inplace=inplace,
conversionError=cubicConversionError,
flattenComponents=flattenComponents,
reverseDirection=reverseDirection,
layerNames=layerNames,
skipExportGlyphs=skipExportGlyphs,
Expand Down Expand Up @@ -353,6 +360,7 @@ def compileInterpolatableTTFsFromDS(
useProductionNames=None,
cubicConversionError=None,
reverseDirection=True,
flattenComponents=False,
inplace=False,
debugFeatureFile=None,
notdefGlyph=None,
Expand Down Expand Up @@ -407,6 +415,7 @@ def compileInterpolatableTTFsFromDS(
useProductionNames=useProductionNames,
cubicConversionError=cubicConversionError,
reverseDirection=reverseDirection,
flattenComponents=flattenComponents,
inplace=inplace,
layerNames=layerNames,
skipExportGlyphs=skipExportGlyphs,
Expand Down Expand Up @@ -568,6 +577,7 @@ def compileVariableTTF(
reverseDirection=True,
excludeVariationTables=(),
optimizeGvar=True,
flattenComponents=False,
inplace=False,
debugFeatureFile=None,
notdefGlyph=None,
Expand Down Expand Up @@ -597,6 +607,7 @@ def compileVariableTTF(
useProductionNames=False, # will rename glyphs after varfont is built
cubicConversionError=cubicConversionError,
reverseDirection=reverseDirection,
flattenComponents=flattenComponents,
inplace=inplace,
debugFeatureFile=debugFeatureFile,
notdefGlyph=notdefGlyph,
Expand Down
21 changes: 18 additions & 3 deletions Lib/ufo2ft/preProcessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ class TTFPreProcessor(OTFPreProcessor):
"""Preprocessor for building TrueType-flavored OpenType fonts.
By default, it decomposes all the glyphs with mixed component/contour
outlines.
outlines. If the ``flattenComponents`` setting is True, glyphs with
nested components are flattened so that they have at most one level of
components.
If ``removeOverlaps`` is True, it performs a union boolean operation on
all the glyphs' contours.
Expand Down Expand Up @@ -144,6 +146,7 @@ def initDefaultFilters(
self,
removeOverlaps=False,
overlapsBackend=None,
flattenComponents=False,
convertCubics=True,
conversionError=None,
reverseDirection=True,
Expand All @@ -157,6 +160,10 @@ def initDefaultFilters(
# that have both components and at least one contour
filters.append(DecomposeComponentsFilter(include=lambda g: len(g)))

if flattenComponents:
from ufo2ft.filters.flattenComponents import FlattenComponentsFilter
filters.append(FlattenComponentsFilter())

if removeOverlaps:
from ufo2ft.filters.removeOverlaps import RemoveOverlapsFilter

Expand Down Expand Up @@ -196,14 +203,16 @@ class TTFInterpolatablePreProcessor(object):
be interpolation compatible, depending on the particular filter used or
whether they are applied to only some vs all of the UFOs.
The ``conversionError``, ``reverseDirection`` and ``rememberCurveType``
arguments work in the same way as in the ``TTFPreProcessor``.
The ``conversionError``, ``reverseDirection``, ``flattenComponents`` and
``rememberCurveType`` arguments work in the same way as in the
``TTFPreProcessor``.
"""

def __init__(
self,
ufos,
inplace=False,
flattenComponents=False,
conversionError=None,
reverseDirection=True,
rememberCurveType=True,
Expand All @@ -214,6 +223,7 @@ def __init__(

self.ufos = ufos
self.inplace = inplace
self.flattenComponents = flattenComponents

if layerNames is None:
layerNames = [None] * len(ufos)
Expand Down Expand Up @@ -260,6 +270,11 @@ def process(self):
for ufo, glyphSet in zip(self.ufos, self.glyphSets):
decompose(ufo, glyphSet)

if self.flattenComponents:
from ufo2ft.filters.flattenComponents import FlattenComponentsFilter
for ufo, glyphSet in zip(self.ufos, self.glyphSets):
FlattenComponentsFilter()(ufo, glyphSet)

# finally apply all custom post-filters
for funcs, ufo, glyphSet in zip(self.postFilters, self.ufos, self.glyphSets):
for func in funcs:
Expand Down
189 changes: 189 additions & 0 deletions tests/data/NestedComponents-Bold.ufo/fontinfo.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ascender</key>
<integer>750</integer>
<key>capHeight</key>
<integer>750</integer>
<key>descender</key>
<integer>-250</integer>
<key>italicAngle</key>
<real>-12.5</real>
<key>macintoshFONDFamilyID</key>
<integer>15000</integer>
<key>macintoshFONDName</key>
<string>SomeFont Regular (FOND Name)</string>
<key>note</key>
<string>A note.</string>
<key>openTypeHeadCreated</key>
<string>2000/01/01 00:00:00</string>
<key>openTypeHeadFlags</key>
<array>
<integer>0</integer>
<integer>1</integer>
</array>
<key>openTypeHeadLowestRecPPEM</key>
<integer>10</integer>
<key>openTypeHheaCaretOffset</key>
<integer>0</integer>
<key>openTypeHheaCaretSlopeRise</key>
<integer>1</integer>
<key>openTypeHheaCaretSlopeRun</key>
<integer>0</integer>
<key>openTypeNameCompatibleFullName</key>
<string>Some Font Regular (Compatible Full Name)</string>
<key>openTypeNameDescription</key>
<string>Some Font by Some Designer for Some Foundry.</string>
<key>openTypeNameDesigner</key>
<string>Some Designer</string>
<key>openTypeNameDesignerURL</key>
<string>http://somedesigner.com</string>
<key>openTypeNameLicense</key>
<string>License info for Some Foundry.</string>
<key>openTypeNameLicenseURL</key>
<string>http://somefoundry.com/license</string>
<key>openTypeNameManufacturer</key>
<string>Some Foundry</string>
<key>openTypeNameManufacturerURL</key>
<string>http://somefoundry.com</string>
<key>openTypeNamePreferredFamilyName</key>
<string>Some Font (Preferred Family Name)</string>
<key>openTypeNameSampleText</key>
<string>Sample Text for Some Font.</string>
<key>openTypeNameUniqueID</key>
<string>OpenType name Table Unique ID</string>
<key>openTypeNameVersion</key>
<string>OpenType name Table Version</string>
<key>openTypeNameWWSFamilyName</key>
<string>Some Font (WWS Family Name)</string>
<key>openTypeNameWWSSubfamilyName</key>
<string>Regular (WWS Subfamily Name)</string>
<key>openTypeOS2CodePageRanges</key>
<array>
<integer>0</integer>
</array>
<key>openTypeOS2FamilyClass</key>
<array>
<integer>1</integer>
<integer>1</integer>
</array>
<key>openTypeOS2Panose</key>
<array>
<integer>0</integer>
<integer>1</integer>
<integer>2</integer>
<integer>3</integer>
<integer>4</integer>
<integer>5</integer>
<integer>6</integer>
<integer>7</integer>
<integer>8</integer>
<integer>9</integer>
</array>
<key>openTypeOS2Selection</key>
<array>
<integer>3</integer>
</array>
<key>openTypeOS2SubscriptXOffset</key>
<integer>0</integer>
<key>openTypeOS2SubscriptXSize</key>
<integer>200</integer>
<key>openTypeOS2SubscriptYOffset</key>
<integer>-100</integer>
<key>openTypeOS2SubscriptYSize</key>
<integer>400</integer>
<key>openTypeOS2SuperscriptXOffset</key>
<integer>0</integer>
<key>openTypeOS2SuperscriptXSize</key>
<integer>200</integer>
<key>openTypeOS2SuperscriptYOffset</key>
<integer>200</integer>
<key>openTypeOS2SuperscriptYSize</key>
<integer>400</integer>
<key>openTypeOS2Type</key>
<array/>
<key>openTypeOS2UnicodeRanges</key>
<array>
<integer>0</integer>
<integer>1</integer>
</array>
<key>openTypeOS2VendorID</key>
<string>SOME</string>
<key>openTypeVheaCaretOffset</key>
<integer>0</integer>
<key>openTypeVheaCaretSlopeRise</key>
<integer>0</integer>
<key>openTypeVheaCaretSlopeRun</key>
<integer>1</integer>
<key>openTypeVheaVertTypoAscender</key>
<integer>750</integer>
<key>openTypeVheaVertTypoDescender</key>
<integer>-250</integer>
<key>openTypeVheaVertTypoLineGap</key>
<integer>200</integer>
<key>postscriptBlueFuzz</key>
<integer>1</integer>
<key>postscriptBlueScale</key>
<real>0.04</real>
<key>postscriptBlueShift</key>
<integer>7</integer>
<key>postscriptBlueValues</key>
<array>
<real>500.0</real>
<real>510.0</real>
</array>
<key>postscriptDefaultCharacter</key>
<string>.notdef</string>
<key>postscriptDefaultWidthX</key>
<integer>400</integer>
<key>postscriptFamilyBlues</key>
<array>
<real>500.0</real>
<real>510.0</real>
</array>
<key>postscriptFamilyOtherBlues</key>
<array>
<real>-260.0</real>
<real>-250.0</real>
</array>
<key>postscriptForceBold</key>
<true/>
<key>postscriptIsFixedPitch</key>
<false/>
<key>postscriptNominalWidthX</key>
<real>400.0</real>
<key>postscriptOtherBlues</key>
<array/>
<key>postscriptSlantAngle</key>
<real>-12.5</real>
<key>postscriptStemSnapH</key>
<array>
<real>0.0</real>
<real>0.0</real>
</array>
<key>postscriptStemSnapV</key>
<array>
<real>0.0</real>
<real>0.0</real>
</array>
<key>postscriptUniqueID</key>
<integer>4000000</integer>
<key>postscriptWindowsCharacterSet</key>
<integer>1</integer>
<key>styleName</key>
<string>Regular</string>
<key>trademark</key>
<string>Trademark Some Foundry</string>
<key>unitsPerEm</key>
<integer>1000</integer>
<key>versionMajor</key>
<integer>1</integer>
<key>versionMinor</key>
<integer>0</integer>
<key>xHeight</key>
<integer>500</integer>
<key>year</key>
<integer>2008</integer>
</dict>
</plist>
18 changes: 18 additions & 0 deletions tests/data/NestedComponents-Bold.ufo/glyphs/_notdef.glif
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<glyph name=".notdef" format="2">
<advance width="500"/>
<outline>
<contour>
<point x="450" y="0" type="line"/>
<point x="450" y="750" type="line"/>
<point x="50" y="750" type="line"/>
<point x="50" y="0" type="line"/>
</contour>
<contour>
<point x="400" y="50" type="line"/>
<point x="100" y="50" type="line"/>
<point x="100" y="700" type="line"/>
<point x="400" y="700" type="line"/>
</contour>
</outline>
</glyph>
13 changes: 13 additions & 0 deletions tests/data/NestedComponents-Bold.ufo/glyphs/a.glif
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<glyph name="a" format="2">
<advance width="510"/>
<unicode hex="0061"/>
<outline>
<contour>
<point x="100" y="505" type="line"/>
<point x="100" y="-5" type="line"/>
<point x="410" y="-5" type="line"/>
<point x="410" y="505" type="line"/>
</contour>
</outline>
</glyph>
21 changes: 21 additions & 0 deletions tests/data/NestedComponents-Bold.ufo/glyphs/b.glif
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<glyph name="b" format="2">
<advance width="449"/>
<unicode hex="0062"/>
<outline>
<contour>
<point x="189" y="234" type="curve"/>
<point x="135" y="234"/>
<point x="91" y="190"/>
<point x="91" y="137" type="curve"/>
<point x="91" y="84"/>
<point x="135" y="40"/>
<point x="189" y="40" type="curve"/>
<point x="242" y="40"/>
<point x="286" y="84"/>
<point x="286" y="137" type="curve"/>
<point x="286" y="190"/>
<point x="242" y="234"/>
</contour>
</outline>
</glyph>
Loading

0 comments on commit c12bac8

Please sign in to comment.