pointPen

PointPens

Where SegmentPens have an intuitive approach to drawing (if you’re familiar with postscript anyway), the PointPen is geared towards accessing all the data in the contours of the glyph. A PointPen has a very simple interface, it just steps through all the points in a call from glyph.drawPoints(). This allows the caller to provide more data for each point. For instance, whether or not a point is smooth, and its name.

class fontTools.pens.pointPen.AbstractPointPen[source]

Baseclass for all PointPens.

addComponent(baseGlyphName: str, transformation: Tuple[float, float, float, float, float, float], identifier: str | None = None, **kwargs: Any) None[source]

Add a sub glyph.

addPoint(pt: Tuple[float, float], segmentType: str | None = None, smooth: bool = False, name: str | None = None, identifier: str | None = None, **kwargs: Any) None[source]

Add a point to the current sub path.

addVarComponent(glyphName: str, transformation: DecomposedTransform, location: Dict[str, float], identifier: str | None = None, **kwargs: Any) None[source]

Add a VarComponent sub glyph. The ‘transformation’ argument must be a DecomposedTransform from the fontTools.misc.transform module, and the ‘location’ argument must be a dictionary mapping axis tags to their locations.

beginPath(identifier: str | None = None, **kwargs: Any) None[source]

Start a new sub path.

endPath() None[source]

End the current sub path.

class fontTools.pens.pointPen.BasePointToSegmentPen[source]

Base class for retrieving the outline in a segment-oriented way. The PointPen protocol is simple yet also a little tricky, so when you need an outline presented as segments but you have as points, do use this base implementation as it properly takes care of all the edge cases.

addComponent(baseGlyphName: str, transformation: Tuple[float, float, float, float, float, float], identifier: str | None = None, **kwargs: Any) None

Add a sub glyph.

addPoint(pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs)[source]

Add a point to the current sub path.

addVarComponent(glyphName: str, transformation: DecomposedTransform, location: Dict[str, float], identifier: str | None = None, **kwargs: Any) None

Add a VarComponent sub glyph. The ‘transformation’ argument must be a DecomposedTransform from the fontTools.misc.transform module, and the ‘location’ argument must be a dictionary mapping axis tags to their locations.

beginPath(identifier=None, **kwargs)[source]

Start a new sub path.

endPath()[source]

End the current sub path.

class fontTools.pens.pointPen.GuessSmoothPointPen(outPen, error=0.05)[source]

Filtering PointPen that tries to determine whether an on-curve point should be “smooth”, ie. that it’s a “tangent” point or a “curve” point.

addComponent(glyphName, transformation, identifier=None, **kwargs)[source]

Add a sub glyph.

addPoint(pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs)[source]

Add a point to the current sub path.

addVarComponent(glyphName, transformation, location, identifier=None, **kwargs)[source]

Add a VarComponent sub glyph. The ‘transformation’ argument must be a DecomposedTransform from the fontTools.misc.transform module, and the ‘location’ argument must be a dictionary mapping axis tags to their locations.

beginPath(identifier=None, **kwargs)[source]

Start a new sub path.

endPath()[source]

End the current sub path.

class fontTools.pens.pointPen.PointToSegmentPen(segmentPen, outputImpliedClosingLine=False)[source]

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.

addComponent(glyphName, transform, identifier=None, **kwargs)[source]

Add a sub glyph.

addPoint(pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs)

Add a point to the current sub path.

addVarComponent(glyphName: str, transformation: DecomposedTransform, location: Dict[str, float], identifier: str | None = None, **kwargs: Any) None

Add a VarComponent sub glyph. The ‘transformation’ argument must be a DecomposedTransform from the fontTools.misc.transform module, and the ‘location’ argument must be a dictionary mapping axis tags to their locations.

beginPath(identifier=None, **kwargs)

Start a new sub path.

endPath()

End the current sub path.

class fontTools.pens.pointPen.ReverseContourPointPen(outputPointPen)[source]

This is a PointPen that passes outline data to another PointPen, but reversing the winding direction of all contours. Components are simply passed through unchanged.

Closed contours are reversed in such a way that the first point remains the first point.

addComponent(glyphName, transform, identifier=None, **kwargs)[source]

Add a sub glyph.

addPoint(pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs)[source]

Add a point to the current sub path.

addVarComponent(glyphName: str, transformation: DecomposedTransform, location: Dict[str, float], identifier: str | None = None, **kwargs: Any) None

Add a VarComponent sub glyph. The ‘transformation’ argument must be a DecomposedTransform from the fontTools.misc.transform module, and the ‘location’ argument must be a dictionary mapping axis tags to their locations.

beginPath(identifier=None, **kwargs)[source]

Start a new sub path.

endPath()[source]

End the current sub path.

class fontTools.pens.pointPen.SegmentToPointPen(pointPen, guessSmooth=True)[source]

Adapter class that converts the (Segment)Pen protocol to the PointPen protocol.

addComponent(glyphName, transform)[source]

Add a sub glyph. The ‘transformation’ argument must be a 6-tuple containing an affine transformation, or a Transform object from the fontTools.misc.transform module. More precisely: it should be a sequence containing 6 numbers.

addVarComponent(glyphName: str, transformation: DecomposedTransform, location: Dict[str, float]) None

Add a VarComponent sub glyph. The ‘transformation’ argument must be a DecomposedTransform from the fontTools.misc.transform module, and the ‘location’ argument must be a dictionary mapping axis tags to their locations.

closePath()[source]

Close the current sub path. You must call either pen.closePath() or pen.endPath() after each sub path.

curveTo(*pts)[source]

Draw a cubic bezier with an arbitrary number of control points.

The last point specified is on-curve, all others are off-curve (control) points. If the number of control points is > 2, the segment is split into multiple bezier segments. This works like this:

Let n be the number of control points (which is the number of arguments to this call minus 1). If n==2, a plain vanilla cubic bezier is drawn. If n==1, we fall back to a quadratic segment and if n==0 we draw a straight line. It gets interesting when n>2: n-1 PostScript-style cubic segments will be drawn as if it were one curve. See decomposeSuperBezierSegment().

The conversion algorithm used for n>2 is inspired by NURB splines, and is conceptually equivalent to the TrueType “implied points” principle. See also decomposeQuadraticSegment().

endPath()[source]

End the current sub path, but don’t close it. You must call either pen.closePath() or pen.endPath() after each sub path.

lineTo(pt)[source]

Draw a straight line from the current point to ‘pt’.

moveTo(pt)[source]

Begin a new sub path, set the current point to ‘pt’. You must end each sub path with a call to pen.closePath() or pen.endPath().

qCurveTo(*pts)[source]

Draw a whole string of quadratic curve segments.

The last point specified is on-curve, all others are off-curve points.

This method implements TrueType-style curves, breaking up curves using ‘implied points’: between each two consequtive off-curve points, there is one implied point exactly in the middle between them. See also decomposeQuadraticSegment().

The last argument (normally the on-curve point) may be None. This is to support contours that have NO on-curve points (a rarely seen feature of TrueType outlines).