Skip to content

Commit

Permalink
Merge pull request #1848 from googlefonts/cu2qu-filter
Browse files Browse the repository at this point in the history
Add convert-to-quadratics filter + test
  • Loading branch information
justvanrossum authored Dec 10, 2024
2 parents 4cfd71f + 1c91cf2 commit 9333106
Show file tree
Hide file tree
Showing 7 changed files with 1,908 additions and 1 deletion.
57 changes: 56 additions & 1 deletion src/fontra/workflow/actions/glyph.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
from dataclasses import dataclass, replace
from typing import Any

from fontTools.cu2qu.ufo import glyphs_to_quadratic
from fontTools.misc.roundTools import otRound
from fontTools.misc.transform import Transform
from fontTools.pens.pointPen import SegmentToPointPen

from ...core.classes import (
Component,
Expand All @@ -17,7 +19,7 @@
StaticGlyph,
VariableGlyph,
)
from ...core.path import PackedPath
from ...core.path import PackedPath, PackedPathPointPen
from ...core.varutils import locationToTuple
from .base import (
BaseFilter,
Expand Down Expand Up @@ -533,3 +535,56 @@ async def processGlyph(self, glyph: VariableGlyph) -> VariableGlyph:
},
)
return glyph


@dataclass(kw_only=True)
class Cu2QuGlyphGlue:
path: PackedPath

def __post_init__(self):
self._pen = None

def clearContours(self):
pass

def drawPoints(self, pen):
self.path.drawPoints(pen)

def getPen(self):
self._pen = PackedPathPointPen()
return SegmentToPointPen(self._pen)

@property
def modifiedPath(self):
return self._pen.getPath() if self._pen is not None else self.path


@registerFilterAction("convert-to-quadratics")
@dataclass(kw_only=True)
class ConvertToQuadratics(BaseFilter):
maximumError: float | None = None
reverseDirection: bool = False

async def processGlyph(self, glyph):
# TODO: we should split by discrete subspace so we can support discrete axes
layers = {
source.layerName: glyph.layers[source.layerName]
for source in getActiveSources(glyph.sources)
}
wrappedPaths = [
Cu2QuGlyphGlue(path=layer.glyph.path) for layer in layers.values()
]
if glyphs_to_quadratic(
wrappedPaths,
max_err=self.maximumError,
reverse_direction=self.reverseDirection,
):
newLayers = dict(glyph.layers)
for (layerName, layer), wrappedPath in zip(layers.items(), wrappedPaths):
newLayers[layerName] = replace(
layer, glyph=replace(layer.glyph, path=wrappedPath.modifiedPath)
)

glyph = replace(glyph, layers=newLayers)

return glyph
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
{
"axes": {
"axes": [
{
"name": "width",
"label": "width",
"tag": "wdth",
"minValue": 0,
"defaultValue": 0,
"maxValue": 1000
},
{
"name": "weight",
"label": "weight",
"tag": "wght",
"minValue": 100,
"defaultValue": 100,
"maxValue": 900,
"mapping": [
[
100,
150
],
[
900,
850
]
]
},
{
"name": "italic",
"label": "italic",
"tag": "ital",
"values": [
0,
1
],
"defaultValue": 0
}
]
},
"sources": {
"3aa9223b": {
"name": "Support",
"location": {
"italic": 0,
"weight": 595,
"width": 0
},
"lineMetricsHorizontalLayout": {
"ascender": {
"value": 800,
"zone": 16
},
"capHeight": {
"value": 750,
"zone": 16
},
"xHeight": {
"value": 500,
"zone": 16
},
"baseline": {
"value": 0,
"zone": -16
},
"descender": {
"value": -250,
"zone": -16
}
}
},
"5bea6334": {
"name": "LightCondensed",
"location": {
"italic": 0,
"weight": 150,
"width": 0
},
"lineMetricsHorizontalLayout": {
"ascender": {
"value": 800,
"zone": 16
},
"capHeight": {
"value": 750,
"zone": 16
},
"xHeight": {
"value": 500,
"zone": 16
},
"baseline": {
"value": 0,
"zone": -16
},
"descender": {
"value": -250,
"zone": -16
}
}
},
"5d4e7f1d": {
"name": "BoldWide",
"location": {
"italic": 0,
"weight": 850,
"width": 1000
},
"lineMetricsHorizontalLayout": {
"ascender": {
"value": 800,
"zone": 16
},
"capHeight": {
"value": 750,
"zone": 16
},
"xHeight": {
"value": 500,
"zone": 16
},
"baseline": {
"value": 0,
"zone": -16
},
"descender": {
"value": -250,
"zone": -16
}
}
},
"d7abd222": {
"name": "LightWide",
"location": {
"italic": 0,
"weight": 150,
"width": 1000
},
"lineMetricsHorizontalLayout": {
"ascender": {
"value": 800,
"zone": 16
},
"capHeight": {
"value": 750,
"zone": 16
},
"xHeight": {
"value": 500,
"zone": 16
},
"baseline": {
"value": 0,
"zone": -16
},
"descender": {
"value": -250,
"zone": -16
}
}
},
"f22d1bbd": {
"name": "BoldCondensed",
"location": {
"italic": 0,
"weight": 850,
"width": 0
},
"lineMetricsHorizontalLayout": {
"ascender": {
"value": 800,
"zone": 16
},
"capHeight": {
"value": 750,
"zone": 16
},
"xHeight": {
"value": 500,
"zone": 16
},
"baseline": {
"value": 0,
"zone": -16
},
"descender": {
"value": -250,
"zone": -16
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
glyph name;code points
A;U+0041,U+0061
B;U+0042,U+0062
Loading

0 comments on commit 9333106

Please sign in to comment.