U
    Dvf.                     @   s   d Z ddlmZmZ ddlmZmZ dddddd	g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re	 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   ?/tmp/pip-unpacked-wheel-qlge9rch/fontTools/pens/recordingPen.pyr      s    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   a8  Pen recording operations that can be accessed or replayed.

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

    :Example:

            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__4   s    zRecordingPen.__init__c                 C   s   | j d|ff d S )NmoveTor   append)r   Zp0r   r   r   r   7   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   Zpointsr   r   r   r   =   s    zRecordingPen.qCurveToc                 G   s   | j d|f d S )NcurveTor   r   r   r   r   r   @   s    zRecordingPen.curveToc                 C   s   | j d d S )N)	closePathr   r   r   r   r   r   r   C   s    zRecordingPen.closePathc                 C   s   | j d d S )N)endPathr   r   r   r   r   r   r    F   s    zRecordingPen.endPathc                 C   s   | j d||ff d S )NaddComponentr   )r   	glyphNametransformationr   r   r   r!   I   s    zRecordingPen.addComponentc                 C   s   | j d|||ff d S )NaddVarComponentr   )r   r"   r#   locationr   r   r   r$   L   s    zRecordingPen.addVarComponentc                 C   s   t | j| d S r   )r   r   )r   r   r   r   r   replayO   s    zRecordingPen.replayN)__name__
__module____qualname____doc__r   r   r   r   r   r   r    r!   r$   r&   Zdrawr   r   r   r   r      s   c                   @   s   e Zd ZdZdZdS )r   a  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*   ZskipMissingComponentsr   r   r   r   r   U   s   4c                   @   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
   as  PointPen recording operations that can be accessed or replayed.

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

    :Example:

            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 k	r||d< | j dd|f d S )N
identifier	beginPathr   r   )r   r,   kwargsr   r   r   r-      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 k	r||d< | j d||||f|f d S )Nr,   addPointr   )r   ptZsegmentTypeZsmoothnamer,   r.   r   r   r   r/      s    zRecordingPointPen.addPointc                 K   s*   |d k	r||d< | j d||f|f d S )Nr,   r!   r   )r   baseGlyphNamer#   r,   r.   r   r   r   r!      s    zRecordingPointPen.addComponentc                 K   s,   |d k	r||d< | j d|||f|f d S )Nr,   r$   r   )r   r2   r#   r%   r,   r.   r   r   r   r$      s
    z!RecordingPointPen.addVarComponentc                 C   s&   | j D ]\}}}t|||| qd S r   )r   r   )r   ZpointPenr   argsr.   r   r   r   r&      s    zRecordingPointPen.replay)N)NFNN)N)N)r'   r(   r)   r*   r   r-   r    r/   r!   r$   r&   Z
drawPointsr   r   r   r   r
      s   
       

 
	c                   @   s   e Zd ZdZdZdS )r	   ay  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   V      ?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y1Zx2y2factorr   r   
<listcomp><  s   z"lerpRecordings.<locals>.<listcomp>N)len
ValueErrorzip)Z
recording1Z
recording2r:   Zop1Zargs1Zop2Zargs2Zmid_argsr   r9   r   r   '  s    

__main__)r   r   )r   d   )2   K   )<   rA   )rA      )pprintN)r4   )r*   ZfontTools.pens.basePenr   r   ZfontTools.pens.pointPenr   r   __all__r   r   r   r
   r	   r   r'   r   r   r   r   r   rE   r   r   r   r   r   <module>   s.   
88@Z


