move dropImpliedOnCurvePoints function to glyf table module

so it can be used by client code on multiple glyf Glyph objects regardles of TTGlyphPen
This commit is contained in:
Cosimo Lupo 2023-05-25 13:42:29 +01:00
parent a73abc6b87
commit b7f4e9b83e
No known key found for this signature in database
GPG Key ID: DF65A8A5A119C9A8
2 changed files with 59 additions and 54 deletions

View File

@ -11,65 +11,13 @@ from fontTools.ttLib.tables._g_l_y_f import flagOnCurve, flagCubic
from fontTools.ttLib.tables._g_l_y_f import Glyph
from fontTools.ttLib.tables._g_l_y_f import GlyphComponent
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
from fontTools.ttLib.tables._g_l_y_f import dropImpliedOnCurvePoints
import math
__all__ = ["TTGlyphPen", "TTGlyphPointPen"]
def drop_implied_oncurves(*interpolatable_glyphs):
drop = None
for glyph in interpolatable_glyphs:
may_drop = set()
start = 0
flags = glyph.flags
coords = glyph.coordinates
for last in glyph.endPtsOfContours:
for i in range(start, last + 1):
if not (flags[i] & flagOnCurve):
continue
prv = i - 1 if i > start else last
nxt = i + 1 if i < last else start
if (flags[prv] & flagOnCurve) or flags[prv] != flags[nxt]:
continue
p0 = coords[prv]
p1 = coords[i]
p2 = coords[nxt]
if not math.isclose(p1[0] - p0[0], p2[0] - p1[0]) or not math.isclose(
p1[1] - p0[1], p2[1] - p1[1]
):
continue
may_drop.add(i)
# we only want to drop if ALL interpolatable glyphs have the same implied oncurves
if drop is None:
drop = may_drop
else:
drop.intersection_update(may_drop)
if drop:
# Do the actual dropping
for glyph in interpolatable_glyphs:
glyph.coordinates = GlyphCoordinates(
coords[i] for i in range(len(coords)) if i not in drop
)
glyph.flags = array("B", (flags[i] for i in range(len(flags)) if i not in drop))
endPts = glyph.endPtsOfContours
newEndPts = []
i = 0
delta = 0
for d in sorted(drop):
while d > endPts[i]:
newEndPts.append(endPts[i] - delta)
i += 1
delta += 1
while i < len(endPts):
newEndPts.append(endPts[i] - delta)
i += 1
glyph.endPtsOfContours = newEndPts
class _TTGlyphBasePen:
def __init__(
self,
@ -199,7 +147,7 @@ class _TTGlyphBasePen:
glyph.coordinates.toInt()
if dropImpliedOnCurves:
drop_implied_oncurves(glyph)
dropImpliedOnCurvePoints(glyph)
self.init()

View File

@ -22,6 +22,7 @@ import sys
import struct
import array
import logging
import math
import os
from fontTools.misc import xmlWriter
from fontTools.misc.filenames import userNameToFileName
@ -1530,6 +1531,62 @@ class Glyph(object):
return result if result is NotImplemented else not result
def dropImpliedOnCurvePoints(*interpolatable_glyphs):
drop = None
for glyph in interpolatable_glyphs:
may_drop = set()
start = 0
flags = glyph.flags
coords = glyph.coordinates
for last in glyph.endPtsOfContours:
for i in range(start, last + 1):
if not (flags[i] & flagOnCurve):
continue
prv = i - 1 if i > start else last
nxt = i + 1 if i < last else start
if (flags[prv] & flagOnCurve) or flags[prv] != flags[nxt]:
continue
p0 = coords[prv]
p1 = coords[i]
p2 = coords[nxt]
if not math.isclose(p1[0] - p0[0], p2[0] - p1[0]) or not math.isclose(
p1[1] - p0[1], p2[1] - p1[1]
):
continue
may_drop.add(i)
# we only want to drop if ALL interpolatable glyphs have the same implied oncurves
if drop is None:
drop = may_drop
else:
drop.intersection_update(may_drop)
if drop:
# Do the actual dropping
for glyph in interpolatable_glyphs:
coords = glyph.coordinates
glyph.coordinates = GlyphCoordinates(
coords[i] for i in range(len(coords)) if i not in drop
)
glyph.flags = array.array(
"B", (flags[i] for i in range(len(flags)) if i not in drop)
)
endPts = glyph.endPtsOfContours
newEndPts = []
i = 0
delta = 0
for d in sorted(drop):
while d > endPts[i]:
newEndPts.append(endPts[i] - delta)
i += 1
delta += 1
while i < len(endPts):
newEndPts.append(endPts[i] - delta)
i += 1
glyph.endPtsOfContours = newEndPts
class GlyphComponent(object):
"""Represents a component within a composite glyph.