�
��g�B � � � d Z ddlmZmZ ddlmZ ddlmZmZ g d�Z G d� de
� � Z G d� d e� � Z G d
� d� � Z
G d� d
e
� � Z G d� dee
� � Z G d� de� � Z G d� de� � Z G d� de� � Zd� Zd� Z G d� de� � Zedk r� ed� � Ze� d� � e� d� � e� ddd d� � e� � � ed� � Ze� ddd!d"d� � e� � � dS dS )#a� fontTools.pens.basePen.py -- Tools and base classes to build pen objects.
The Pen Protocol
A Pen is a kind of object that standardizes the way how to "draw" outlines:
it is a middle man between an outline and a drawing. In other words:
it is an abstraction for drawing outlines, making sure that outline objects
don't need to know the details about how and where they're being drawn, and
that drawings don't need to know the details of how outlines are stored.
The most basic pattern is this::
outline.draw(pen) # 'outline' draws itself onto 'pen'
Pens can be used to render outlines to the screen, but also to construct
new outlines. Eg. an outline object can be both a drawable object (it has a
draw() method) as well as a pen itself: you *build* an outline using pen
methods.
The AbstractPen class defines the Pen protocol. It implements almost
nothing (only no-op closePath() and endPath() methods), but is useful
for documentation purposes. Subclassing it basically tells the reader:
"this class implements the Pen protocol.". An examples of an AbstractPen
subclass is :py:class:`fontTools.pens.transformPen.TransformPen`.
The BasePen class is a base implementation useful for pens that actually
draw (for example a pen renders outlines using a native graphics engine).
BasePen contains a lot of base functionality, making it very easy to build
a pen that fully conforms to the pen protocol. Note that if you subclass
BasePen, you *don't* override moveTo(), lineTo(), etc., but _moveTo(),
_lineTo(), etc. See the BasePen doc string for details. Examples of
BasePen subclasses are fontTools.pens.boundsPen.BoundsPen and
fontTools.pens.cocoaPen.CocoaPen.
Coordinates are usually expressed as (x, y) tuples, but generally any
sequence of length 2 will do.
� )�Tuple�Dict)�LogMixin)�DecomposedTransform�Identity)�AbstractPen�NullPen�BasePen�PenError�decomposeSuperBezierSegment�decomposeQuadraticSegmentc � � e Zd ZdZdS )r z#Represents an error during penning.N��__name__�
__module__�__qualname__�__doc__� � �f/home/asafur/pinokio/api/open-webui.git/app/env/lib/python3.11/site-packages/fontTools/pens/basePen.pyr r 6 s � � � � � �-�-�-�-r r c � � e Zd ZdS )�OpenContourErrorN)r r r r r r r r : s � � � � � ��Dr r c
�� � e Zd Zdeeef ddfd�Zdeeef ddfd�Zdeeef ddfd�Zdeeef ddfd�Zdd �Z dd
�Z
dedeeeeeeef ddfd
�Zdede
deeef ddfd�ZdS )r �pt�returnNc � � t �)z�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().
��NotImplementedError��selfr s r �moveTozAbstractPen.moveTo? s
� � "�!r c � � t �)z4Draw a straight line from the current point to 'pt'.r r s r �lineTozAbstractPen.lineToE s � �!�!r �pointsc � � t �)a� 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().
r �r r$ s r �curveTozAbstractPen.curveToI s
� �&