Skip to content

Commit

Permalink
add allQuadratic=False option to allow building glyf v1 with cubics
Browse files Browse the repository at this point in the history
a mix of cubics or quadratic depending on which is more economical
  • Loading branch information
anthrotype committed Jul 28, 2023
1 parent 6003361 commit ea4d3eb
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Lib/ufo2ft/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ def compileOTF(ufo, **kwargs):
flattenComponents=False,
autoUseMyMetrics=True,
dropImpliedOnCurves=False,
allQuadratic=True,
),
}

Expand Down Expand Up @@ -252,6 +253,10 @@ def compileTTF(ufo, **kwargs):
*dropImpliedOnCurves* (bool) specifies whether on-curve points that are exactly
in between two off-curves can be dropped when building glyphs (default: False).
*allQuadratic* (bool) specifies whether to convert all curves to quadratic - True
by default, builds traditional glyf v0 table. If False, quadratic curves or cubic
curves are generated depending on which has fewer points; a glyf v1 is generated.
"""
kwargs = init_kwargs(kwargs, compileTTF_args)

Expand Down Expand Up @@ -280,6 +285,7 @@ def compileTTF(ufo, **kwargs):
colrAutoClipBoxes=False,
extraSubstitutions=None,
autoUseMyMetrics=True,
allQuadratic=True,
),
}

Expand Down Expand Up @@ -562,6 +568,7 @@ def compileFeatures(
colrAutoClipBoxes=False,
autoUseMyMetrics=True,
dropImpliedOnCurves=False,
allQuadratic=True,
),
}

Expand Down Expand Up @@ -612,6 +619,10 @@ def compileVariableTTFs(designSpaceDoc: DesignSpaceDocument, **kwargs):
to build. If not provided, all variable fonts listed in the given
designspace will by built.
*allQuadratic* (bool) specifies whether to convert all curves to quadratic - True
by default, builds traditional glyf v0 table. If False, quadratic curves or cubic
curves are generated depending on which has fewer points; a glyf v1 is generated.
The rest of the arguments works the same as in the other compile functions.
Returns a dictionary that maps each variable font filename to a new variable
Expand Down
2 changes: 2 additions & 0 deletions Lib/ufo2ft/filters/cubicToQuadratic.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CubicToQuadraticFilter(BaseFilter):
"conversionError": None,
"reverseDirection": True,
"rememberCurveType": False,
"allQuadratic": True,
}

def set_context(self, font, glyphSet):
Expand Down Expand Up @@ -64,6 +65,7 @@ def filter(self, glyph):
self.context.absoluteError,
reverse_direction=self.options.reverseDirection,
stats=self.context.stats,
all_quadratic=self.options.allQuadratic,
)
contours = list(glyph)
glyph.clearContours()
Expand Down
5 changes: 5 additions & 0 deletions Lib/ufo2ft/preProcessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ def initDefaultFilters(
flattenComponents=False,
convertCubics=True,
conversionError=None,
allQuadratic=True,
reverseDirection=True,
rememberCurveType=True,
):
Expand Down Expand Up @@ -227,6 +228,7 @@ def initDefaultFilters(
conversionError=conversionError,
reverseDirection=reverseDirection,
rememberCurveType=rememberCurveType and self.inplace,
allQuadratic=allQuadratic,
)
)
return filters
Expand Down Expand Up @@ -266,6 +268,7 @@ def __init__(
layerNames=None,
skipExportGlyphs=None,
filters=None,
allQuadratic=True,
):
from fontTools.cu2qu.ufo import DEFAULT_MAX_ERR

Expand Down Expand Up @@ -293,6 +296,7 @@ def __init__(
]
self._reverseDirection = reverseDirection
self._rememberCurveType = rememberCurveType
self.allQuadratic = allQuadratic

self.defaultFilters = []
for ufo in ufos:
Expand Down Expand Up @@ -336,6 +340,7 @@ def process(self):
reverse_direction=self._reverseDirection,
dump_stats=True,
remember_curve_type=self._rememberCurveType and self.inplace,
all_quadratic=self.allQuadratic,
)

# TrueType fonts cannot mix contours and components, so pick out all glyphs
Expand Down
170 changes: 170 additions & 0 deletions tests/data/TestFont-not-allQuadratic.ttx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont>

<glyf>

<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->

<TTGlyph name=".notdef" xMin="50" yMin="0" xMax="450" yMax="750">
<contour>
<pt x="450" y="0" on="1"/>
<pt x="50" y="0" on="1"/>
<pt x="50" y="750" on="1"/>
<pt x="450" y="750" on="1"/>
</contour>
<contour>
<pt x="400" y="50" on="1"/>
<pt x="400" y="700" on="1"/>
<pt x="100" y="700" on="1"/>
<pt x="100" y="50" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni0020"/><!-- contains no outline data -->

<TTGlyph name="uni0061" xMin="66" yMin="0" xMax="322" yMax="510">
<contour>
<pt x="66" y="0" on="1"/>
<pt x="194" y="510" on="1"/>
<pt x="322" y="0" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni0062" xMin="100" yMin="-5" xMax="310" yMax="505">
<contour>
<pt x="100" y="505" on="1"/>
<pt x="310" y="505" on="1"/>
<pt x="310" y="-5" on="1"/>
<pt x="100" y="-5" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni0063" xMin="100" yMin="-10" xMax="300" yMax="500">
<contour>
<pt x="300" y="-10" on="1"/>
<pt x="150" y="-10" on="0" cubic="1"/>
<pt x="100" y="40" on="0" cubic="1"/>
<pt x="100" y="245" on="1"/>
<pt x="100" y="450" on="0" cubic="1"/>
<pt x="150" y="500" on="0" cubic="1"/>
<pt x="300" y="500" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni0064" xMin="90" yMin="77" xMax="211" yMax="197">
<contour>
<pt x="151" y="197" on="1"/>
<pt x="184" y="197" on="0" cubic="1"/>
<pt x="211" y="170" on="0" cubic="1"/>
<pt x="211" y="137" on="1"/>
<pt x="211" y="104" on="0" cubic="1"/>
<pt x="184" y="77" on="0" cubic="1"/>
<pt x="151" y="77" on="1"/>
<pt x="117" y="77" on="0" cubic="1"/>
<pt x="90" y="104" on="0" cubic="1"/>
<pt x="90" y="137" on="1"/>
<pt x="90" y="170" on="0" cubic="1"/>
<pt x="117" y="197" on="0" cubic="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni0065" xMin="-55" yMin="23" xMax="454" yMax="510">
<contour>
<pt x="66" y="510" on="1"/>
<pt x="322" y="510" on="1"/>
<pt x="194" y="75" on="1"/>
</contour>
<contour>
<pt x="-55" y="23" on="1"/>
<pt x="-55" y="173" on="0" cubic="1"/>
<pt x="-5" y="223" on="0" cubic="1"/>
<pt x="199" y="223" on="1"/>
<pt x="404" y="223" on="0" cubic="1"/>
<pt x="454" y="173" on="0" cubic="1"/>
<pt x="454" y="23" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni0066" xMin="-55" yMin="23" xMax="454" yMax="510">
<contour>
<pt x="66" y="510" on="1"/>
<pt x="194" y="75" on="1"/>
<pt x="322" y="510" on="1"/>
</contour>
<contour>
<pt x="-55" y="23" on="1"/>
<pt x="-55" y="173" on="0" cubic="1"/>
<pt x="-5" y="223" on="0" cubic="1"/>
<pt x="199" y="223" on="1"/>
<pt x="404" y="223" on="0" cubic="1"/>
<pt x="454" y="173" on="0" cubic="1"/>
<pt x="454" y="23" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni0067" xMin="66" yMin="0" xMax="322" yMax="510">
<component glyphName="uni0061" x="0" y="0" flags="0x204"/>
</TTGlyph>

<TTGlyph name="uni0068" xMin="100" yMin="-5" xMax="310" yMax="657">
<component glyphName="uni0064" x="60" y="460" flags="0x4"/>
<component glyphName="uni0062" x="0" y="0" flags="0x204"/>
</TTGlyph>

<TTGlyph name="uni0069" xMin="-55" yMin="-80" xMax="454" yMax="510">
<contour>
<pt x="-55" y="-80" on="1"/>
<pt x="-55" y="69" on="0" cubic="1"/>
<pt x="-5" y="119" on="0" cubic="1"/>
<pt x="199" y="119" on="1"/>
<pt x="404" y="119" on="0" cubic="1"/>
<pt x="454" y="69" on="0" cubic="1"/>
<pt x="454" y="-80" on="1"/>
</contour>
<contour>
<pt x="66" y="0" on="1"/>
<pt x="194" y="510" on="1"/>
<pt x="322" y="0" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni006A" xMin="-55" yMin="-280" xMax="454" yMax="230">
<contour>
<pt x="-55" y="-80" on="1"/>
<pt x="-55" y="69" on="0" cubic="1"/>
<pt x="-5" y="119" on="0" cubic="1"/>
<pt x="199" y="119" on="1"/>
<pt x="404" y="119" on="0" cubic="1"/>
<pt x="454" y="69" on="0" cubic="1"/>
<pt x="454" y="-80" on="1"/>
</contour>
<contour>
<pt x="66" y="230" on="1"/>
<pt x="322" y="230" on="1"/>
<pt x="194" y="-280" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="uni006B" xMin="66" yMin="0" xMax="422" yMax="510">
<component glyphName="uni0061" x="0" y="0" flags="0x4"/>
<component glyphName="uni0061" x="100" y="0" flags="0x4"/>
</TTGlyph>

<TTGlyph name="uni006C" xMin="78" yMin="0" xMax="422" yMax="510">
<component glyphName="uni0061" x="400" y="0" scalex="-1.0" scaley="1.0" flags="0x4"/>
<component glyphName="uni0061" x="100" y="0" flags="0x4"/>
</TTGlyph>

</glyf>

</ttFont>
118 changes: 118 additions & 0 deletions tests/data/TestVariableFont-TTF-not-allQuadratic.ttx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont>

<glyf>

<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->

<TTGlyph name=".notdef" xMin="50" yMin="-250" xMax="450" yMax="750">
<contour>
<pt x="50" y="-250" on="1"/>
<pt x="50" y="750" on="1"/>
<pt x="450" y="750" on="1"/>
<pt x="450" y="-250" on="1"/>
</contour>
<contour>
<pt x="100" y="-200" on="1"/>
<pt x="400" y="-200" on="1"/>
<pt x="400" y="700" on="1"/>
<pt x="100" y="700" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="a" xMin="9" yMin="-12" xMax="468" yMax="504">
<contour>
<pt x="468" y="-1" on="1"/>
<pt x="366" y="-3" on="1"/>
<pt x="363" y="357" on="1"/>
<pt x="208" y="397" on="1"/>
<pt x="36" y="337" on="1"/>
<pt x="9" y="428" on="1"/>
<pt x="214" y="504" on="1"/>
<pt x="447" y="434" on="1"/>
</contour>
<contour>
<pt x="378" y="263" on="1"/>
<pt x="382" y="207" on="1"/>
<pt x="88" y="172" on="1"/>
<pt x="86" y="126" on="1"/>
<pt x="161" y="74" on="1"/>
<pt x="383" y="134" on="1"/>
<pt x="389" y="71" on="1"/>
<pt x="168" y="-12" on="1"/>
<pt x="29" y="22" on="1"/>
<pt x="26" y="240" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="curved" xMin="0" yMin="0" xMax="500" yMax="500">
<contour>
<pt x="500" y="0" on="1"/>
<pt x="0" y="0" on="1"/>
<pt x="0" y="277.614" on="0" cubic="1"/>
<pt x="111.928" y="500" on="0" cubic="1"/>
<pt x="250" y="500" on="1"/>
<pt x="388.072" y="500" on="0" cubic="1"/>
<pt x="500" y="277.614" on="0" cubic="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="dotabovecomb" xMin="-37" yMin="501" xMax="50" yMax="597">
<contour>
<pt x="-21" y="597" on="1"/>
<pt x="50" y="589" on="1"/>
<pt x="41" y="501" on="1"/>
<pt x="-37" y="503" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="e" xMin="40" yMin="-18" xMax="576" yMax="513">
<contour>
<pt x="127" y="228" on="1"/>
<pt x="125" y="298" on="1"/>
<pt x="480" y="292" on="1"/>
<pt x="317" y="416" on="1"/>
<pt x="147" y="263" on="1"/>
<pt x="229" y="75" on="1"/>
<pt x="509" y="129" on="1"/>
<pt x="526" y="45" on="1"/>
<pt x="188" y="-18" on="1"/>
<pt x="40" y="261" on="1"/>
<pt x="316" y="513" on="1"/>
<pt x="571" y="305" on="1"/>
<pt x="576" y="226" on="1"/>
</contour>
<instructions/>
</TTGlyph>

<TTGlyph name="edotabove" xMin="40" yMin="-18" xMax="576" yMax="693">
<component glyphName="e" x="0" y="0" flags="0x204"/>
<component glyphName="dotabovecomb" x="313" y="96" flags="0x4"/>
</TTGlyph>

<TTGlyph name="s" xMin="25" yMin="-13" xMax="582" yMax="530">
<contour>
<pt x="559" y="459" on="1"/>
<pt x="539" y="376" on="1"/>
<pt x="326" y="442" on="1"/>
<pt x="213" y="366" on="1"/>
<pt x="582" y="174" on="1"/>
<pt x="304" y="-13" on="1"/>
<pt x="25" y="83" on="1"/>
<pt x="53" y="174" on="1"/>
<pt x="282" y="76" on="1"/>
<pt x="427" y="155" on="1"/>
<pt x="38" y="343" on="1"/>
<pt x="324" y="530" on="1"/>
</contour>
<instructions/>
</TTGlyph>

</glyf>

</ttFont>
Loading

0 comments on commit ea4d3eb

Please sign in to comment.