Skip to content

Commit

Permalink
[varLib.mutator] Improve CharString rounding
Browse files Browse the repository at this point in the history
Since CharString point coordinates are relative, rounding each point
independently can accumulate rounding errors causing to the last point
to not match the first one, which leads to rendering artifacts.

This is a hack to round the absolute point coordinates, but using pens
to convert the relative coordinates to absolute ones and back.

This is a hack since it drops hinting operators, and it can’t preserve
the original operators, in addition to being slower.

There is probably a more clever way to doing this.
  • Loading branch information
khaledhosny committed Apr 13, 2024
1 parent 8caf16c commit 5a347b7
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
6 changes: 5 additions & 1 deletion Lib/fontTools/pens/t2CharStringPen.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _closePath(self):
def _endPath(self):
pass

def getCharString(self, private=None, globalSubrs=None, optimize=True):
def getProgram(self, optimize=True):
commands = self._commands
if optimize:
maxstack = 48 if not self._CFF2 else 513
Expand All @@ -62,6 +62,10 @@ def getCharString(self, private=None, globalSubrs=None, optimize=True):
program.insert(0, otRound(self._width))
if not self._CFF2:
program.append("endchar")
return program

def getCharString(self, private=None, globalSubrs=None, optimize=True):
program = self.getProgram(optimize=optimize)
charString = T2CharString(
program=program, private=private, globalSubrs=globalSubrs
)
Expand Down
10 changes: 9 additions & 1 deletion Lib/fontTools/varLib/mutator.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ def interpolate_cff2_PrivateDict(topDict, interpolateFromDeltas):


def interpolate_cff2_charstrings(topDict, interpolateFromDeltas, glyphOrder):
from fontTools.pens.t2CharStringPen import T2CharStringPen

charstrings = topDict.CharStrings
for gname in glyphOrder:
# Interpolate charstring
Expand Down Expand Up @@ -100,7 +102,7 @@ def interpolate_cff2_charstrings(topDict, interpolateFromDeltas, glyphOrder):
next_ti = tuplei + num_regions
deltas = charstring.program[tuplei:next_ti]
delta = interpolateFromDeltas(vsindex, deltas)
charstring.program[argi] += otRound(delta)
charstring.program[argi] += delta
tuplei = next_ti
argi += 1
new_program.extend(charstring.program[last_i:end_args])
Expand All @@ -109,6 +111,12 @@ def interpolate_cff2_charstrings(topDict, interpolateFromDeltas, glyphOrder):
new_program.extend(charstring.program[last_i:])
charstring.program = new_program

# Rebuild charstring program by passing it through T2CharStringPen which
# will have the side effect of rounding coordinates.
t2Pen = T2CharStringPen(width=None, glyphSet=None)
charstring.draw(t2Pen)
charstring.program = t2Pen.getProgram(optimize=True)


def interpolate_cff2_metrics(varfont, topDict, glyphOrder, loc):
"""Unlike TrueType glyphs, neither advance width nor bounding box
Expand Down
21 changes: 11 additions & 10 deletions Tests/varLib/data/test_results/InterpolateTestCFF2VF.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -34,35 +34,33 @@
84 hmoveto
432 660 -432 hlineto
48 -628 rmoveto
102 176 64 106 rlineto
4 hlineto
62 -106 100 -176 rlineto
102 176 64 106 4 0 62 -106 100 -176 rlineto
-342 42 rmoveto
536 vlineto
154 -270 rlineto
22 26 rmoveto
-56 92 -94 168 rlineto
302 hlineto
-94 -168 -54 -92 rlineto
-56 92 -94 168 302 0 -94 -168 -54 -92 rlineto
22 -26 rmoveto
152 270 rlineto
-536 vlineto
endchar
</CharString>
<CharString name="A">
50 hmoveto
32 hlineto
140 396 28 80 24 68 24 82 rlinecurve
4 hlineto
24 -82 24 -68 28 -80 138 -396 rcurveline
34 hlineto
-236 660 rlineto
24 -82 24 -68 28 -80 rrcurveto
138 -396 34 0 -236 660 rlineto
-28 hlineto
-134 -424 rmoveto
293 28 -293 hlineto
endchar
</CharString>
<CharString name="T">
284 hmoveto
32 632 234 28 -500 -28 234 hlineto
endchar
</CharString>
<CharString name="dollar">
311 34 rmoveto
Expand All @@ -74,14 +72,16 @@
-99 -78 -54 -88 hvcurveto
-166 338 28 -156 vvcurveto
-70 -56 -50 -103 -85 -66 38 34 -40 vhcurveto
-18 -22 45 -38 73 -40 91 0 rlinecurve
-18 -22 rlineto
-38 45 73 -40 91 hhcurveto
-18 566 rmoveto
30 hlineto
50 0 50 50 vvcurveto
-30 hlineto
-50 0 -50 -50 vvcurveto
-562 vmoveto
-148 30 148 vlineto
endchar
</CharString>
<CharString name="glyph00003">
311 34 rmoveto
Expand All @@ -97,6 +97,7 @@
-38 45 73 -40 91 hhcurveto
-70 -146 rmoveto
158 860 -30 4 -158 -860 rlineto
endchar
</CharString>
</CharStrings>
</CFFFont>
Expand Down

0 comments on commit 5a347b7

Please sign in to comment.