# pointPen: Point-oriented pen classes

This module contains base classes for point-oriented pens.

## 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

  Bases: `object`

  Baseclass for all PointPens.

  beginPath(identifier: str | None = None, **kwargs: Any) → None

    Start a new sub path.

  endPath() → None

    End the current sub path.

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

    Add a point to the current sub path.

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

    Add a sub glyph.

  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.

class fontTools.pens.pointPen.BasePointToSegmentPen

  Bases: `AbstractPointPen`

  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.

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

class fontTools.pens.pointPen.PointToSegmentPen(segmentPen, outputImpliedClosingLine: bool = False)

  Bases: `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.

  addComponent(glyphName, transform, identifier=None, **kwargs)

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

  Bases: `AbstractPen`

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

  moveTo(pt)
  lineTo(pt)
  curveTo(*pts)
  qCurveTo(*pts)
  closePath()
  endPath()
  addComponent(glyphName, transform)

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

  Bases: `AbstractPointPen`

  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.

  beginPath(identifier=None, **kwargs)
  endPath()
  addPoint(pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs)
  addComponent(glyphName, transformation, identifier=None, **kwargs)
  addVarComponent(glyphName, transformation, location, identifier=None, **kwargs)

class fontTools.pens.pointPen.ReverseContourPointPen(outputPointPen)

  Bases: `AbstractPointPen`

  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.

  beginPath(identifier=None, **kwargs)
  endPath()
  addPoint(pt, segmentType=None, smooth=False, name=None, identifier=None, **kwargs)
  addComponent(glyphName, transform, identifier=None, **kwargs)

class fontTools.pens.pointPen.ReverseFlipped(*values)

  Bases: `StrEnum`

  How to handle flipped components during decomposition.

  NO: Don’t reverse flipped components KEEP_START: Reverse flipped components, keeping original starting point ON_CURVE_FIRST: Reverse flipped components, ensuring first point is on-curve

  NO = 'no'
  KEEP_START = 'keep_start'
  ON_CURVE_FIRST = 'on_curve_first'