Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify pen argument names #2919

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion Lib/fontTools/cu2qu/ufo.py
Expand Up @@ -24,6 +24,7 @@
"""

import logging
from typing import Tuple
from fontTools.pens.basePen import AbstractPen
from fontTools.pens.pointPen import PointToSegmentPen
from fontTools.pens.reverseContourPen import ReverseContourPen
Expand Down Expand Up @@ -91,7 +92,11 @@ def closePath(self):
def endPath(self):
self._add_segment('end')

def addComponent(self, glyphName, transformation):
def addComponent(
self,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mixing tabs and spaces?
feels weird we add typing only to this method and not the rest. Maybe for now just rename the parameters if you don't have time to add type hints to all.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C&P error ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've started to add typing annotations to the pens. But I had to stop now, because it gets complicated and even requires some code rewriting to pass the type checks. But at least there is more typing than before now :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, where would it require code rewriting?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to add some assertions, otherwise the type checker would complain about variables possibly being None, e.g.:

https://github.com/fonttools/fonttools/pull/2919/files#diff-713c63d7dd345e61c8c06754b31811b60345f57b1b2c70fdf7bb8aaf7227c92aR408-R420

glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
) -> None:
pass


Expand Down
16 changes: 12 additions & 4 deletions Lib/fontTools/pens/basePen.py
Expand Up @@ -36,7 +36,7 @@
sequence of length 2 will do.
"""

from typing import Tuple
from typing import Any, Optional, Tuple

from fontTools.misc.loggingTools import LogMixin

Expand Down Expand Up @@ -116,7 +116,7 @@ def endPath(self) -> None:
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float]
transformation: Tuple[float, float, float, float, float, float],
) -> None:
"""Add a sub glyph. The 'transformation' argument must be a 6-tuple
containing an affine transformation, or a Transform object from the
Expand Down Expand Up @@ -149,7 +149,11 @@ def closePath(self):
def endPath(self):
pass

def addComponent(self, glyphName, transformation):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
) -> None:
pass


Expand Down Expand Up @@ -186,7 +190,11 @@ def __init__(self, glyphSet):
super(DecomposingPen, self).__init__()
self.glyphSet = glyphSet

def addComponent(self, glyphName, transformation):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
) -> None:
""" Transform the points of the base glyph and draw it onto self.
"""
from fontTools.pens.transformPen import TransformPen
Expand Down
17 changes: 14 additions & 3 deletions Lib/fontTools/pens/cu2quPen.py
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Any, Optional, Tuple
from fontTools.cu2qu import curve_to_quadratic
from fontTools.pens.basePen import AbstractPen, decomposeSuperBezierSegment
from fontTools.pens.reverseContourPen import ReverseContourPen
Expand Down Expand Up @@ -131,7 +132,11 @@ def endPath(self):
self.pen.endPath()
self.current_pt = self.start_pt = None

def addComponent(self, glyphName, transformation):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
) -> None:
self._check_contour_is_closed()
self.pen.addComponent(glyphName, transformation)

Expand Down Expand Up @@ -255,6 +260,12 @@ def _drawPoints(self, segments):
pen.addPoint(pt, None, smooth, name, **kwargs)
pen.endPath()

def addComponent(self, baseGlyphName, transformation):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any
) -> None:
assert self.currentPath is None
self.pen.addComponent(baseGlyphName, transformation)
self.pen.addComponent(glyphName, transformation, identifier, **kwargs)
33 changes: 29 additions & 4 deletions Lib/fontTools/pens/filterPen.py
@@ -1,12 +1,29 @@
from typing import Any, Optional, Tuple
from fontTools.pens.basePen import AbstractPen
from fontTools.pens.pointPen import AbstractPointPen
from fontTools.pens.recordingPen import RecordingPen


class _PassThruComponentsMixin(object):

def addComponent(self, glyphName, transformation, **kwargs):
self._outPen.addComponent(glyphName, transformation, **kwargs)
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
) -> None:
self._outPen.addComponent(glyphName, transformation)


class _PassThruComponentsPointPenMixin(object):

def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any
) -> None:
self._outPen.addComponent(glyphName, transformation, identifier, **kwargs)


class FilterPen(_PassThruComponentsMixin, AbstractPen):
Expand Down Expand Up @@ -120,7 +137,7 @@ def filterContour(self, contour):
return # or return contour


class FilterPointPen(_PassThruComponentsMixin, AbstractPointPen):
class FilterPointPen(_PassThruComponentsPointPenMixin, AbstractPointPen):
""" Baseclass for point pens that apply some transformation to the
coordinates they receive and pass them to another point pen.

Expand Down Expand Up @@ -154,5 +171,13 @@ def beginPath(self, **kwargs):
def endPath(self):
self._outPen.endPath()

def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
def addPoint(
self,
pt: Tuple[float, float],
segmentType: Optional[str] = None,
smooth: bool = False,
name: Optional[str] = None,
identifier: Optional[str] = None,
**kwargs,
) -> None:
self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs)
39 changes: 24 additions & 15 deletions Lib/fontTools/pens/hashPointPen.py
@@ -1,6 +1,7 @@
# Modified from https://github.com/adobe-type-tools/psautohint/blob/08b346865710ed3c172f1eb581d6ef243b203f99/python/psautohint/ufoFont.py#L800-L838
import hashlib

from typing import Any, Dict, Optional, Tuple
from fontTools.pens.basePen import MissingComponentError
from fontTools.pens.pointPen import AbstractPointPen

Expand Down Expand Up @@ -33,45 +34,53 @@ class HashPointPen(AbstractPointPen):
> pass
"""

def __init__(self, glyphWidth=0, glyphSet=None):
def __init__(
self, glyphWidth: float = 0, glyphSet: Optional[Dict[str, Any]] = None
) -> None:
self.glyphset = glyphSet
self.data = ["w%s" % round(glyphWidth, 9)]

@property
def hash(self):
def hash(self) -> str:
data = "".join(self.data)
if len(data) >= 128:
data = hashlib.sha512(data.encode("ascii")).hexdigest()
return data

def beginPath(self, identifier=None, **kwargs):
def beginPath(
self, identifier: Optional[str] = None, **kwargs: Any
) -> None:
pass

def endPath(self):
def endPath(self) -> None:
self.data.append("|")

def addPoint(
self,
pt,
segmentType=None,
smooth=False,
name=None,
identifier=None,
**kwargs,
):
pt: Tuple[float, float],
segmentType: Optional[str] = None,
smooth: bool = False,
name: Optional[str] = None,
identifier: Optional[str] = None,
**kwargs: Any,
) -> None:
if segmentType is None:
pt_type = "o" # offcurve
else:
pt_type = segmentType[0]
self.data.append(f"{pt_type}{pt[0]:g}{pt[1]:+g}")

def addComponent(
self, baseGlyphName, transformation, identifier=None, **kwargs
):
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any,
) -> None:
tr = "".join([f"{t:+}" for t in transformation])
self.data.append("[")
try:
self.glyphset[baseGlyphName].drawPoints(self)
self.glyphset[glyphName].drawPoints(self)
except KeyError:
raise MissingComponentError(baseGlyphName)
raise MissingComponentError(glyphName)
self.data.append(f"({tr})]")
70 changes: 57 additions & 13 deletions Lib/fontTools/pens/pointPen.py
Expand Up @@ -52,7 +52,7 @@ def addPoint(

def addComponent(
self,
baseGlyphName: str,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any
Expand Down Expand Up @@ -154,8 +154,15 @@ def endPath(self):

self._flushContour(segments)

def addPoint(self, pt, segmentType=None, smooth=False, name=None,
identifier=None, **kwargs):
def addPoint(
self,
pt: Tuple[float, float],
segmentType: Optional[str] = None,
smooth: bool = False,
name: Optional[str] = None,
identifier: Optional[str] = None,
**kwargs,
) -> None:
if self.currentPath is None:
raise PenError("Path not begun")
self.currentPath.append((pt, segmentType, smooth, name, kwargs))
Expand Down Expand Up @@ -240,10 +247,16 @@ def _flushContour(self, segments):
else:
pen.endPath()

def addComponent(self, glyphName, transform, identifier=None, **kwargs):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any
) -> None:
del identifier # unused
del kwargs # unused
self.pen.addComponent(glyphName, transform)
self.pen.addComponent(glyphName, transformation)


class SegmentToPointPen(AbstractPen):
Expand Down Expand Up @@ -318,10 +331,14 @@ def endPath(self):
self._flushContour()
self.contour = None

def addComponent(self, glyphName, transform):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
) -> None:
if self.contour is not None:
raise PenError("Components must be added before or after contours")
self.pen.addComponent(glyphName, transform)
self.pen.addComponent(glyphName, transformation)


class GuessSmoothPointPen(AbstractPointPen):
Expand Down Expand Up @@ -388,15 +405,28 @@ def endPath(self):
self._outPen.endPath()
self._points = None

def addPoint(self, pt, segmentType=None, smooth=False, name=None,
identifier=None, **kwargs):
def addPoint(
self,
pt: Tuple[float, float],
segmentType: Optional[str] = None,
smooth: bool = False,
name: Optional[str] = None,
identifier: Optional[str] = None,
**kwargs,
) -> None:
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):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any
) -> None:
if self._points is not None:
raise PenError("Components must be added before or after contours")
if identifier is not None:
Expand Down Expand Up @@ -480,14 +510,28 @@ def endPath(self):
self._flushContour()
self.currentContour = None

def addPoint(self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs):
def addPoint(
self,
pt: Tuple[float, float],
segmentType: Optional[str] = None,
smooth: bool = False,
name: Optional[str] = None,
identifier: Optional[str] = None,
**kwargs,
) -> None:
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):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any
) -> 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)
self.pen.addComponent(glyphName, transformation, identifier, **kwargs)
21 changes: 18 additions & 3 deletions Lib/fontTools/pens/recordingPen.py
@@ -1,4 +1,5 @@
"""Pen recording operations that can be accessed or replayed."""
from typing import Any, Optional, Tuple
from fontTools.pens.basePen import AbstractPen, DecomposingPen
from fontTools.pens.pointPen import AbstractPointPen

Expand Down Expand Up @@ -130,15 +131,29 @@ def beginPath(self, identifier=None, **kwargs):
def endPath(self):
self.value.append(("endPath", (), {}))

def addPoint(self, pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs):
def addPoint(
self,
pt: Tuple[float, float],
segmentType: Optional[str] = None,
smooth: bool = False,
name: Optional[str] = None,
identifier: Optional[str] = None,
**kwargs,
) -> None:
if identifier is not None:
kwargs["identifier"] = identifier
self.value.append(("addPoint", (pt, segmentType, smooth, name), kwargs))

def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs):
def addComponent(
self,
glyphName: str,
transformation: Tuple[float, float, float, float, float, float],
identifier: Optional[str] = None,
**kwargs: Any
) -> None:
if identifier is not None:
kwargs["identifier"] = identifier
self.value.append(("addComponent", (baseGlyphName, transformation), kwargs))
self.value.append(("addComponent", (glyphName, transformation), kwargs))

def replay(self, pointPen):
for operator, args, kwargs in self.value:
Expand Down