a
    ¥Q•hÉ0  ã                   @   sÔ   d Z ddlmZmZ ddlmZmZ g d¢Zdd„ ZG dd„ deƒZ	G d	d
„ d
ee	ƒZ
G dd„ deƒZG dd„ deeƒZddd„ZedkrÐe	ƒ Ze d¡ e d¡ e ddd¡ e ¡  ddlmZ eejƒ dS )z:Pen recording operations that can be accessed or replayed.é    )ÚAbstractPenÚDecomposingPen)ÚAbstractPointPenÚDecomposingPointPen)ÚreplayRecordingÚRecordingPenÚDecomposingRecordingPenÚDecomposingRecordingPointPenÚRecordingPointPenÚlerpRecordingsc                 C   s    | D ]\}}t ||ƒ|Ž  qdS )a2  Replay a recording, as produced by RecordingPen or DecomposingRecordingPen,
    to a pen.

    Note that recording does not have to be produced by those pens.
    It can be any iterable of tuples of method name and tuple-of-arguments.
    Likewise, pen can be any objects receiving those method calls.
    N)Úgetattr)Z	recordingÚpenÚoperatorZoperands© r   úT/var/www/sistema_ama/venv/lib/python3.9/site-packages/fontTools/pens/recordingPen.pyr      s    r   c                   @   sd   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZeZdS )r   aP  Pen recording operations that can be accessed or replayed.

    The recording can be accessed as pen.value; or replayed using
    pen.replay(otherPen).

    :Example:
        .. code-block::

            from fontTools.ttLib import TTFont
            from fontTools.pens.recordingPen import RecordingPen

            glyph_name = 'dollar'
            font_path = 'MyFont.otf'

            font = TTFont(font_path)
            glyphset = font.getGlyphSet()
            glyph = glyphset[glyph_name]

            pen = RecordingPen()
            glyph.draw(pen)
            print(pen.value)
    c                 C   s
   g | _ d S ©N©Úvalue©Úselfr   r   r   Ú__init__5   s    zRecordingPen.__init__c                 C   s   | j  d|ff¡ d S )NÚmoveTo©r   Úappend)r   Úp0r   r   r   r   8   s    zRecordingPen.moveToc                 C   s   | j  d|ff¡ d S )NÚlineTor   )r   Úp1r   r   r   r   ;   s    zRecordingPen.lineToc                 G   s   | j  d|f¡ d S )NÚqCurveTor   ©r   Úpointsr   r   r   r   >   s    zRecordingPen.qCurveToc                 G   s   | j  d|f¡ d S )NÚcurveTor   r   r   r   r   r    A   s    zRecordingPen.curveToc                 C   s   | j  d¡ d S )N)Ú	closePathr   r   r   r   r   r   r!   D   s    zRecordingPen.closePathc                 C   s   | j  d¡ d S )N)ÚendPathr   r   r   r   r   r   r"   G   s    zRecordingPen.endPathc                 C   s   | j  d||ff¡ d S )NÚaddComponentr   )r   Ú	glyphNameÚtransformationr   r   r   r#   J   s    zRecordingPen.addComponentc                 C   s   | j  d|||ff¡ d S )NÚaddVarComponentr   )r   r$   r%   Úlocationr   r   r   r&   M   s    zRecordingPen.addVarComponentc                 C   s   t | j|ƒ d S r   )r   r   )r   r   r   r   r   ÚreplayP   s    zRecordingPen.replayN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r    r!   r"   r#   r&   r(   Údrawr   r   r   r   r      s   r   c                   @   s   e Zd ZdZdZdS )r   aa	  Same as RecordingPen, except that it doesn't keep components
    as references, but draws them decomposed as regular contours.

    The constructor takes a required 'glyphSet' positional argument,
    a dictionary of glyph objects (i.e. with a 'draw' method) keyed
    by thir name; other arguments are forwarded to the DecomposingPen's
    constructor::

        >>> class SimpleGlyph(object):
        ...     def draw(self, pen):
        ...         pen.moveTo((0, 0))
        ...         pen.curveTo((1, 1), (2, 2), (3, 3))
        ...         pen.closePath()
        >>> class CompositeGlyph(object):
        ...     def draw(self, pen):
        ...         pen.addComponent('a', (1, 0, 0, 1, -1, 1))
        >>> class MissingComponent(object):
        ...     def draw(self, pen):
        ...         pen.addComponent('foobar', (1, 0, 0, 1, 0, 0))
        >>> class FlippedComponent(object):
        ...     def draw(self, pen):
        ...         pen.addComponent('a', (-1, 0, 0, 1, 0, 0))
        >>> glyphSet = {
        ...    'a': SimpleGlyph(),
        ...    'b': CompositeGlyph(),
        ...    'c': MissingComponent(),
        ...    'd': FlippedComponent(),
        ... }
        >>> for name, glyph in sorted(glyphSet.items()):
        ...     pen = DecomposingRecordingPen(glyphSet)
        ...     try:
        ...         glyph.draw(pen)
        ...     except pen.MissingComponentError:
        ...         pass
        ...     print("{}: {}".format(name, pen.value))
        a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())]
        b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())]
        c: []
        d: [('moveTo', ((0, 0),)), ('curveTo', ((-1, 1), (-2, 2), (-3, 3))), ('closePath', ())]

        >>> for name, glyph in sorted(glyphSet.items()):
        ...     pen = DecomposingRecordingPen(
        ...         glyphSet, skipMissingComponents=True, reverseFlipped=True,
        ...     )
        ...     glyph.draw(pen)
        ...     print("{}: {}".format(name, pen.value))
        a: [('moveTo', ((0, 0),)), ('curveTo', ((1, 1), (2, 2), (3, 3))), ('closePath', ())]
        b: [('moveTo', ((-1, 1),)), ('curveTo', ((0, 2), (1, 3), (2, 4))), ('closePath', ())]
        c: []
        d: [('moveTo', ((0, 0),)), ('lineTo', ((-3, 3),)), ('curveTo', ((-2, 2), (-1, 1), (0, 0))), ('closePath', ())]
    FN©r)   r*   r+   r,   ÚskipMissingComponentsr   r   r   r   r   V   s   5r   c                   @   sT   e Zd ZdZdd„ Zddd„Zdd„ Zdd
d„Zddd„Zddd„Z	dd„ Z
e
ZdS )r
   a‹  PointPen recording operations that can be accessed or replayed.

    The recording can be accessed as pen.value; or replayed using
    pointPen.replay(otherPointPen).

    :Example:
        .. code-block::

            from defcon import Font
            from fontTools.pens.recordingPen import RecordingPointPen

            glyph_name = 'a'
            font_path = 'MyFont.ufo'

            font = Font(font_path)
            glyph = font[glyph_name]

            pen = RecordingPointPen()
            glyph.drawPoints(pen)
            print(pen.value)

            new_glyph = font.newGlyph('b')
            pen.replay(new_glyph.getPointPen())
    c                 C   s
   g | _ d S r   r   r   r   r   r   r   ©   s    zRecordingPointPen.__init__Nc                 K   s&   |d ur||d< | j  dd|f¡ d S )NÚ
identifierÚ	beginPathr   r   )r   r0   Úkwargsr   r   r   r1   ¬   s    zRecordingPointPen.beginPathc                 C   s   | j  ddi f¡ d S )Nr"   r   r   r   r   r   r   r"   ±   s    zRecordingPointPen.endPathFc                 K   s.   |d ur||d< | j  d||||f|f¡ d S )Nr0   ÚaddPointr   )r   ÚptÚsegmentTypeÚsmoothÚnamer0   r2   r   r   r   r3   ´   s    zRecordingPointPen.addPointc                 K   s*   |d ur||d< | j  d||f|f¡ d S )Nr0   r#   r   )r   ÚbaseGlyphNamer%   r0   r2   r   r   r   r#   »   s    zRecordingPointPen.addComponentc                 K   s,   |d ur||d< | j  d|||f|f¡ d S )Nr0   r&   r   )r   r8   r%   r'   r0   r2   r   r   r   r&   À   s
    ÿz!RecordingPointPen.addVarComponentc                 C   s*   | j D ]\}}}t||ƒ|i |¤Ž qd S r   )r   r   )r   ÚpointPenr   Úargsr2   r   r   r   r(   É   s    zRecordingPointPen.replay)N)NFNN)N)N)r)   r*   r+   r,   r   r1   r"   r3   r#   r&   r(   Ú
drawPointsr   r   r   r   r
   �   s   
 ÿ

 ÿ
	r
   c                   @   s   e Zd ZdZdZdS )r	   a¦  Same as RecordingPointPen, except that it doesn't keep components
    as references, but draws them decomposed as regular contours.

    The constructor takes a required 'glyphSet' positional argument,
    a dictionary of pointPen-drawable glyph objects (i.e. with a 'drawPoints' method)
    keyed by thir name; other arguments are forwarded to the DecomposingPointPen's
    constructor::

        >>> from pprint import pprint
        >>> class SimpleGlyph(object):
        ...     def drawPoints(self, pen):
        ...         pen.beginPath()
        ...         pen.addPoint((0, 0), "line")
        ...         pen.addPoint((1, 1))
        ...         pen.addPoint((2, 2))
        ...         pen.addPoint((3, 3), "curve")
        ...         pen.endPath()
        >>> class CompositeGlyph(object):
        ...     def drawPoints(self, pen):
        ...         pen.addComponent('a', (1, 0, 0, 1, -1, 1))
        >>> class MissingComponent(object):
        ...     def drawPoints(self, pen):
        ...         pen.addComponent('foobar', (1, 0, 0, 1, 0, 0))
        >>> class FlippedComponent(object):
        ...     def drawPoints(self, pen):
        ...         pen.addComponent('a', (-1, 0, 0, 1, 0, 0))
        >>> glyphSet = {
        ...    'a': SimpleGlyph(),
        ...    'b': CompositeGlyph(),
        ...    'c': MissingComponent(),
        ...    'd': FlippedComponent(),
        ... }
        >>> for name, glyph in sorted(glyphSet.items()):
        ...     pen = DecomposingRecordingPointPen(glyphSet)
        ...     try:
        ...         glyph.drawPoints(pen)
        ...     except pen.MissingComponentError:
        ...         pass
        ...     pprint({name: pen.value})
        {'a': [('beginPath', (), {}),
               ('addPoint', ((0, 0), 'line', False, None), {}),
               ('addPoint', ((1, 1), None, False, None), {}),
               ('addPoint', ((2, 2), None, False, None), {}),
               ('addPoint', ((3, 3), 'curve', False, None), {}),
               ('endPath', (), {})]}
        {'b': [('beginPath', (), {}),
               ('addPoint', ((-1, 1), 'line', False, None), {}),
               ('addPoint', ((0, 2), None, False, None), {}),
               ('addPoint', ((1, 3), None, False, None), {}),
               ('addPoint', ((2, 4), 'curve', False, None), {}),
               ('endPath', (), {})]}
        {'c': []}
        {'d': [('beginPath', (), {}),
               ('addPoint', ((0, 0), 'line', False, None), {}),
               ('addPoint', ((-1, 1), None, False, None), {}),
               ('addPoint', ((-2, 2), None, False, None), {}),
               ('addPoint', ((-3, 3), 'curve', False, None), {}),
               ('endPath', (), {})]}

        >>> for name, glyph in sorted(glyphSet.items()):
        ...     pen = DecomposingRecordingPointPen(
        ...         glyphSet, skipMissingComponents=True, reverseFlipped=True,
        ...     )
        ...     glyph.drawPoints(pen)
        ...     pprint({name: pen.value})
        {'a': [('beginPath', (), {}),
               ('addPoint', ((0, 0), 'line', False, None), {}),
               ('addPoint', ((1, 1), None, False, None), {}),
               ('addPoint', ((2, 2), None, False, None), {}),
               ('addPoint', ((3, 3), 'curve', False, None), {}),
               ('endPath', (), {})]}
        {'b': [('beginPath', (), {}),
               ('addPoint', ((-1, 1), 'line', False, None), {}),
               ('addPoint', ((0, 2), None, False, None), {}),
               ('addPoint', ((1, 3), None, False, None), {}),
               ('addPoint', ((2, 4), 'curve', False, None), {}),
               ('endPath', (), {})]}
        {'c': []}
        {'d': [('beginPath', (), {}),
               ('addPoint', ((0, 0), 'curve', False, None), {}),
               ('addPoint', ((-3, 3), 'line', False, None), {}),
               ('addPoint', ((-2, 2), None, False, None), {}),
               ('addPoint', ((-1, 1), None, False, None), {}),
               ('endPath', (), {})]}
    FNr.   r   r   r   r   r	   Ð   s   Wr	   ç      à?c                 #   s”   t | ƒt |ƒkr(tdt | ƒt |ƒf ƒ‚t| |ƒD ]\\\}}\}}||krZtd||f ƒ‚|dkrltdƒ‚n‡ fdd„t||ƒD ƒ}||fV  q2dS )a¤  Linearly interpolate between two recordings. The recordings
    must be decomposed, i.e. they must not contain any components.

    Factor is typically between 0 and 1. 0 means the first recording,
    1 means the second recording, and 0.5 means the average of the
    two recordings. Other values are possible, and can be useful to
    extrapolate. Defaults to 0.5.

    Returns a generator with the new recording.
    zMismatched lengths: %d and %dzMismatched operations: %s, %sr#   zCannot interpolate componentsc                    s8   g | ]0\\}}\}}||| ˆ   ||| ˆ   f‘qS r   r   )Ú.0Úx1Úy1Úx2Úy2©Úfactorr   r   Ú
<listcomp>@  s   ÿz"lerpRecordings.<locals>.<listcomp>N)ÚlenÚ
ValueErrorÚzip)Ú
recording1Ú
recording2rC   Zop1Zargs1Zop2Zargs2Zmid_argsr   rB   r   r   +  s    ÿ

þr   Ú__main__)r   r   )r   éd   )é2   éK   )é<   rL   )rL   é   )ÚpprintN)r<   )r,   ÚfontTools.pens.basePenr   r   ÚfontTools.pens.pointPenr   r   Ú__all__r   r   r   r
   r	   r   r)   r   r   r   r    r!   rP   r   r   r   r   r   Ú<module>   s"   
99A[


