Closed arialcrime closed 2 years ago
will make a PR
from fontTools.pens.pointPen import AbstractPointPen
class FilterRedundantPointPen(AbstractPointPen):
def __init__(self, anotherPointPen):
self._pen = anotherPointPen
self._points = []
def _flushContour(self):
# convert to a list of mutable dicts
# keep the point order
# keep a flag if the point will be removed
points = [
dict(
pt=pt,
segmentType=segmentType,
smooth=smooth,
name=name,
identifier=identifier,
removed=False
)
for pt, segmentType, smooth, name, identifier in self._points
]
for index, data in enumerate(points):
if data["segmentType"] == "curve":
prevOnCurve = points[index - 3]
prevOffCurve1 = points[index -2]
prevOffCurve2 = points[index - 1]
if prevOnCurve["pt"] == prevOffCurve1["pt"] and prevOffCurve2["pt"] == data["pt"]:
# the off curves are on top of the on curve point
# change the segmentType
data["segmentType"] = "line"
# flag the off curves to be removed
prevOffCurve1["removed"] = True
prevOffCurve2["removed"] = True
for data in points:
if not data["removed"]:
self._pen.addPoint(
data["pt"],
data["segmentType"],
smooth=data["smooth"],
name=data["name"],
identifier=data["identifier"]
)
def beginPath(self, identifier=None, **kwargs):
self._points = []
self._pen.beginPath(identifier=identifier)
def addPoint(self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs):
self._points.append((pt, segmentType, smooth, name, identifier))
def endPath(self):
self._flushContour()
self._pen.endPath()
def addComponent(self, baseGlyph, transformation, identifier=None, **kwargs):
self._pen.addComponent(baseGlyph, transformation, identifier)
from fontPens.printPointPen import PrintPointPen
pen = FilterRedundantPointPen(PrintPointPen())
pen.beginPath()
pen.addPoint((298, 132))
pen.addPoint((298, 80))
pen.addPoint((298, 80), segmentType="curve")
pen.addPoint((600, 80), segmentType="line")
pen.addPoint((600, 132), segmentType="line")
pen.addPoint((298, 132), segmentType="line")
pen.endPath()
pen.beginPath()
pen.addPoint((298, 80), segmentType="curve")
pen.addPoint((600, 80), segmentType="line")
pen.addPoint((600, 132), segmentType="line")
pen.addPoint((298, 132), segmentType="line")
pen.addPoint((298, 132))
pen.addPoint((298, 80))
pen.endPath()
pen.beginPath()
pen.addPoint((298, 80))
pen.addPoint((298, 80), segmentType="curve")
pen.addPoint((600, 80), segmentType="line")
pen.addPoint((600, 132), segmentType="line")
pen.addPoint((298, 132), segmentType="line")
pen.addPoint((298, 132))
pen.endPath()
pen.beginPath()
pen.addPoint((298, 132))
pen.addPoint((298, 81))
pen.addPoint((298, 80), segmentType="curve")
pen.addPoint((600, 80), segmentType="line")
pen.addPoint((600, 132), segmentType="line")
pen.addPoint((298, 132), segmentType="line")
pen.endPath()
pen.beginPath()
pen.addPoint((298, 80), segmentType="curve")
pen.addPoint((600, 80), segmentType="line")
pen.addPoint((600, 132), segmentType="line")
pen.addPoint((298, 132), segmentType="line")
pen.addPoint((298, 132))
pen.addPoint((298, 81))
pen.endPath()
I came across a situation where depending on the start point,
FilterRedundantPointPen
is not able to catch redundant offcurve points.In a glyph like the one here, the offcurve points stay in place after running the pen.
In the case below,
FilterRedundantPointPen
works as expected by getting rid of the 2 points without a type.