aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/pens/pointPen.py
diff options
context:
space:
mode:
authorRod S <rsheeter@google.com>2022-03-25 22:07:18 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-03-25 22:07:18 +0000
commit29956f91d34a6e7e114e9e04c4c22296e20b80c8 (patch)
tree98d81cb66669c50af608fd8a844e22039a00f5ae /Lib/fontTools/pens/pointPen.py
parentec30550b149d3ba5c81fc88f2f90dd171b3f4013 (diff)
parent3886b0a80e36b841df5bf1b790cfd2bb92764f15 (diff)
downloadfonttools-c8e612d79d7d9aee2ad9b0f68bb1a84fc796081b.tar.gz
Update FontTools to 4.31.2 to gain access to iterSubTables. am: 0b59a54a78 am: 3e24ea754b am: 3886b0a80et_frc_odp_330442040t_frc_odp_330442000t_frc_ase_330444010android-13.0.0_r83android-13.0.0_r82android-13.0.0_r81android-13.0.0_r80android-13.0.0_r79android-13.0.0_r78android-13.0.0_r77android-13.0.0_r76android-13.0.0_r75android-13.0.0_r74android-13.0.0_r73android-13.0.0_r72android-13.0.0_r71android-13.0.0_r70android-13.0.0_r69android-13.0.0_r68android-13.0.0_r67android-13.0.0_r66android-13.0.0_r65android-13.0.0_r64android-13.0.0_r63android-13.0.0_r62android-13.0.0_r61android-13.0.0_r60android-13.0.0_r59android-13.0.0_r58android-13.0.0_r57android-13.0.0_r56android-13.0.0_r54android-13.0.0_r53android-13.0.0_r52android-13.0.0_r51android-13.0.0_r50android-13.0.0_r49android-13.0.0_r48android-13.0.0_r47android-13.0.0_r46android-13.0.0_r45android-13.0.0_r44android-13.0.0_r43android-13.0.0_r42android-13.0.0_r41android-13.0.0_r40android-13.0.0_r39android-13.0.0_r38android-13.0.0_r37android-13.0.0_r36android-13.0.0_r35android-13.0.0_r34android-13.0.0_r33android-13.0.0_r32android13-qpr3-s9-releaseandroid13-qpr3-s8-releaseandroid13-qpr3-s7-releaseandroid13-qpr3-s6-releaseandroid13-qpr3-s5-releaseandroid13-qpr3-s4-releaseandroid13-qpr3-s3-releaseandroid13-qpr3-s2-releaseandroid13-qpr3-s14-releaseandroid13-qpr3-s13-releaseandroid13-qpr3-s12-releaseandroid13-qpr3-s11-releaseandroid13-qpr3-s10-releaseandroid13-qpr3-s1-releaseandroid13-qpr3-releaseandroid13-qpr3-c-s8-releaseandroid13-qpr3-c-s7-releaseandroid13-qpr3-c-s6-releaseandroid13-qpr3-c-s5-releaseandroid13-qpr3-c-s4-releaseandroid13-qpr3-c-s3-releaseandroid13-qpr3-c-s2-releaseandroid13-qpr3-c-s12-releaseandroid13-qpr3-c-s11-releaseandroid13-qpr3-c-s10-releaseandroid13-qpr3-c-s1-releaseandroid13-qpr2-s9-releaseandroid13-qpr2-s8-releaseandroid13-qpr2-s7-releaseandroid13-qpr2-s6-releaseandroid13-qpr2-s5-releaseandroid13-qpr2-s3-releaseandroid13-qpr2-s2-releaseandroid13-qpr2-s12-releaseandroid13-qpr2-s11-releaseandroid13-qpr2-s10-releaseandroid13-qpr2-s1-releaseandroid13-qpr2-releaseandroid13-qpr2-b-s1-releaseandroid13-frc-odp-releaseandroid13-devandroid13-d4-s2-releaseandroid13-d4-s1-releaseandroid13-d4-releaseandroid13-d3-s1-release
Original change: https://android-review.googlesource.com/c/platform/external/fonttools/+/2043270 Change-Id: Ie02c14d6e2550eb53669c28030dcf2c938419d6e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'Lib/fontTools/pens/pointPen.py')
-rw-r--r--Lib/fontTools/pens/pointPen.py89
1 files changed, 62 insertions, 27 deletions
diff --git a/Lib/fontTools/pens/pointPen.py b/Lib/fontTools/pens/pointPen.py
index 26f99d41..4c3148bf 100644
--- a/Lib/fontTools/pens/pointPen.py
+++ b/Lib/fontTools/pens/pointPen.py
@@ -15,7 +15,7 @@ For instance, whether or not a point is smooth, and its name.
import math
from typing import Any, Optional, Tuple
-from fontTools.pens.basePen import AbstractPen
+from fontTools.pens.basePen import AbstractPen, PenError
__all__ = [
"AbstractPointPen",
@@ -74,7 +74,8 @@ class BasePointToSegmentPen(AbstractPointPen):
self.currentPath = None
def beginPath(self, identifier=None, **kwargs):
- assert self.currentPath is None
+ if self.currentPath is not None:
+ raise PenError("Path already begun.")
self.currentPath = []
def _flushContour(self, segments):
@@ -106,7 +107,8 @@ class BasePointToSegmentPen(AbstractPointPen):
raise NotImplementedError
def endPath(self):
- assert self.currentPath is not None
+ if self.currentPath is None:
+ raise PenError("Path not begun.")
points = self.currentPath
self.currentPath = None
if not points:
@@ -154,6 +156,8 @@ class BasePointToSegmentPen(AbstractPointPen):
def addPoint(self, pt, segmentType=None, smooth=False, name=None,
identifier=None, **kwargs):
+ if self.currentPath is None:
+ raise PenError("Path not begun")
self.currentPath.append((pt, segmentType, smooth, name, kwargs))
@@ -161,6 +165,9 @@ class PointToSegmentPen(BasePointToSegmentPen):
"""
Adapter class that converts the PointPen protocol to the
(Segment)Pen protocol.
+
+ NOTE: The segment pen does not support and will drop point names, identifiers
+ and kwargs.
"""
def __init__(self, segmentPen, outputImpliedClosingLine=False):
@@ -169,21 +176,23 @@ class PointToSegmentPen(BasePointToSegmentPen):
self.outputImpliedClosingLine = outputImpliedClosingLine
def _flushContour(self, segments):
- assert len(segments) >= 1
+ if not segments:
+ raise PenError("Must have at least one segment.")
pen = self.pen
if segments[0][0] == "move":
# It's an open path.
closed = False
points = segments[0][1]
- assert len(points) == 1, "illegal move segment point count: %d" % len(points)
- movePt, smooth, name, kwargs = points[0]
+ if len(points) != 1:
+ raise PenError(f"Illegal move segment point count: {len(points)}")
+ movePt, _, _ , _ = points[0]
del segments[0]
else:
# It's a closed path, do a moveTo to the last
# point of the last segment.
closed = True
segmentType, points = segments[-1]
- movePt, smooth, name, kwargs = points[-1]
+ movePt, _, _ , _ = points[-1]
if movePt is None:
# quad special case: a contour with no on-curve points contains
# one "qcurve" segment that ends with a point that's None. We
@@ -196,9 +205,10 @@ class PointToSegmentPen(BasePointToSegmentPen):
lastPt = movePt
for i in range(nSegments):
segmentType, points = segments[i]
- points = [pt for pt, smooth, name, kwargs in points]
+ points = [pt for pt, _, _ , _ in points]
if segmentType == "line":
- assert len(points) == 1, "illegal line segment point count: %d" % len(points)
+ if len(points) != 1:
+ raise PenError(f"Illegal line segment point count: {len(points)}")
pt = points[0]
# For closed contours, a 'lineTo' is always implied from the last oncurve
# point to the starting point, thus we can omit it when the last and
@@ -224,7 +234,7 @@ class PointToSegmentPen(BasePointToSegmentPen):
pen.qCurveTo(*points)
lastPt = points[-1]
else:
- assert 0, "illegal segmentType: %s" % segmentType
+ raise PenError(f"Illegal segmentType: {segmentType}")
if closed:
pen.closePath()
else:
@@ -232,6 +242,7 @@ class PointToSegmentPen(BasePointToSegmentPen):
def addComponent(self, glyphName, transform, identifier=None, **kwargs):
del identifier # unused
+ del kwargs # unused
self.pen.addComponent(glyphName, transform)
@@ -260,27 +271,35 @@ class SegmentToPointPen(AbstractPen):
self.contour.append((pt, "move"))
def lineTo(self, pt):
- assert self.contour is not None, "contour missing required initial moveTo"
+ if self.contour is None:
+ raise PenError("Contour missing required initial moveTo")
self.contour.append((pt, "line"))
def curveTo(self, *pts):
- assert self.contour is not None, "contour missing required initial moveTo"
+ if not pts:
+ raise TypeError("Must pass in at least one point")
+ if self.contour is None:
+ raise PenError("Contour missing required initial moveTo")
for pt in pts[:-1]:
self.contour.append((pt, None))
self.contour.append((pts[-1], "curve"))
def qCurveTo(self, *pts):
+ if not pts:
+ raise TypeError("Must pass in at least one point")
if pts[-1] is None:
self.contour = []
else:
- assert self.contour is not None, "contour missing required initial moveTo"
+ if self.contour is None:
+ raise PenError("Contour missing required initial moveTo")
for pt in pts[:-1]:
self.contour.append((pt, None))
if pts[-1] is not None:
self.contour.append((pts[-1], "qcurve"))
def closePath(self):
- assert self.contour is not None, "contour missing required initial moveTo"
+ if self.contour is None:
+ raise PenError("Contour missing required initial moveTo")
if len(self.contour) > 1 and self.contour[0][0] == self.contour[-1][0]:
self.contour[0] = self.contour[-1]
del self.contour[-1]
@@ -294,12 +313,14 @@ class SegmentToPointPen(AbstractPen):
self.contour = None
def endPath(self):
- assert self.contour is not None, "contour missing required initial moveTo"
+ if self.contour is None:
+ raise PenError("Contour missing required initial moveTo")
self._flushContour()
self.contour = None
def addComponent(self, glyphName, transform):
- assert self.contour is None
+ if self.contour is not None:
+ raise PenError("Components must be added before or after contours")
self.pen.addComponent(glyphName, transform)
@@ -309,11 +330,14 @@ class GuessSmoothPointPen(AbstractPointPen):
should be "smooth", ie. that it's a "tangent" point or a "curve" point.
"""
- def __init__(self, outPen):
+ def __init__(self, outPen, error=0.05):
self._outPen = outPen
+ self._error = error
self._points = None
def _flushContour(self):
+ if self._points is None:
+ raise PenError("Path not begun")
points = self._points
nPoints = len(points)
if not nPoints:
@@ -329,7 +353,7 @@ class GuessSmoothPointPen(AbstractPointPen):
# closed path containing 1 point (!), ignore.
indices = []
for i in indices:
- pt, segmentType, dummy, name, kwargs = points[i]
+ pt, segmentType, _, name, kwargs = points[i]
if segmentType is None:
continue
prev = i - 1
@@ -343,16 +367,17 @@ class GuessSmoothPointPen(AbstractPointPen):
if pt != prevPt and pt != nextPt:
dx1, dy1 = pt[0] - prevPt[0], pt[1] - prevPt[1]
dx2, dy2 = nextPt[0] - pt[0], nextPt[1] - pt[1]
- a1 = math.atan2(dx1, dy1)
- a2 = math.atan2(dx2, dy2)
- if abs(a1 - a2) < 0.05:
+ a1 = math.atan2(dy1, dx1)
+ a2 = math.atan2(dy2, dx2)
+ if abs(a1 - a2) < self._error:
points[i] = pt, segmentType, True, name, kwargs
for pt, segmentType, smooth, name, kwargs in points:
self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs)
def beginPath(self, identifier=None, **kwargs):
- assert self._points is None
+ if self._points is not None:
+ raise PenError("Path already begun")
self._points = []
if identifier is not None:
kwargs["identifier"] = identifier
@@ -365,12 +390,15 @@ class GuessSmoothPointPen(AbstractPointPen):
def addPoint(self, pt, segmentType=None, smooth=False, name=None,
identifier=None, **kwargs):
+ if self._points is None:
+ raise PenError("Path not begun")
if identifier is not None:
kwargs["identifier"] = identifier
self._points.append((pt, segmentType, False, name, kwargs))
def addComponent(self, glyphName, transformation, identifier=None, **kwargs):
- assert self._points is None
+ if self._points is not None:
+ raise PenError("Components must be added before or after contours")
if identifier is not None:
kwargs["identifier"] = identifier
self._outPen.addComponent(glyphName, transformation, **kwargs)
@@ -440,19 +468,26 @@ class ReverseContourPointPen(AbstractPointPen):
pen.endPath()
def beginPath(self, identifier=None, **kwargs):
- assert self.currentContour is None
+ if self.currentContour is not None:
+ raise PenError("Path already begun")
self.currentContour = []
self.currentContourIdentifier = identifier
self.onCurve = []
def endPath(self):
- assert self.currentContour is not None
+ if self.currentContour is None:
+ raise PenError("Path not begun")
self._flushContour()
self.currentContour = None
- def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
+ def addPoint(self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs):
+ if self.currentContour is None:
+ raise PenError("Path not begun")
+ if identifier is not None:
+ kwargs["identifier"] = identifier
self.currentContour.append((pt, segmentType, smooth, name, kwargs))
def addComponent(self, glyphName, transform, identifier=None, **kwargs):
- assert self.currentContour is None
+ if self.currentContour is not None:
+ raise PenError("Components must be added before or after contours")
self.pen.addComponent(glyphName, transform, identifier=identifier, **kwargs)