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:
parent
a73abc6b87
commit
b7f4e9b83e
@ -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()
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user