
    ]Mh0                        d Z ddlmZmZ ddlmZmZ g dZd Z G d de          Z	 G d d	ee	          Z
 G d
 de          Z G d dee          ZddZedk    rw e	            Ze                    d           e                    d           e                    ddd           e                                 ddlmZ  eej                   dS dS )z:Pen recording operations that can be accessed or replayed.    )AbstractPenDecomposingPen)AbstractPointPenDecomposingPointPen)replayRecordingRecordingPenDecomposingRecordingPenDecomposingRecordingPointPenRecordingPointPenlerpRecordingsc                 <    | D ]\  }} t          ||          |  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)	recordingpenoperatoroperandss       [/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/fontTools/pens/recordingPen.pyr   r      s<     ( * *(X)))* *    c                   R    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Z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                     g | _         d S Nvalueselfs    r   __init__zRecordingPen.__init__5       


r   c                 @    | j                             d|ff           d S )NmoveTor   append)r   p0s     r   r   zRecordingPen.moveTo8   %    
8bU+,,,,,r   c                 @    | j                             d|ff           d S )NlineTor    )r   p1s     r   r%   zRecordingPen.lineTo;   r#   r   c                 >    | j                             d|f           d S )NqCurveTor    r   pointss     r   r(   zRecordingPen.qCurveTo>   s#    
:v./////r   c                 >    | j                             d|f           d S )NcurveTor    r)   s     r   r,   zRecordingPen.curveToA   s#    
9f-.....r   c                 :    | j                             d           d S )N)	closePath r    r   s    r   r.   zRecordingPen.closePathD   s    
+,,,,,r   c                 :    | j                             d           d S )N)endPathr/   r    r   s    r   r1   zRecordingPen.endPathG   s    
/*****r   c                 B    | j                             d||ff           d S )NaddComponentr    )r   	glyphNametransformations      r   r3   zRecordingPen.addComponentJ   s(    
>I~+FGHHHHHr   c                 D    | j                             d|||ff           d S )NaddVarComponentr    )r   r4   r5   locations       r   r7   zRecordingPen.addVarComponentM   s+    
,y.(.STUUUUUr   c                 0    t          | j        |           d S r   )r   r   )r   r   s     r   replayzRecordingPen.replayP   s    
C(((((r   N)__name__
__module____qualname____doc__r   r   r%   r(   r,   r.   r1   r3   r7   r:   drawr/   r   r   r   r      s         .  - - -- - -0 0 0/ / /- - -+ + +I I IV V V) ) ) DDDr   r   c                       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#        2 2j "r   r	   c                   L    e Zd ZdZd ZddZd Z	 ddZddZ	 dd	Z	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                     g | _         d S r   r   r   s    r   r   zRecordingPointPen.__init__   r   r   Nc                 N    |||d<   | j                             dd|f           d S )N
identifier	beginPathr/   r    )r   rF   kwargss      r   rG   zRecordingPointPen.beginPath   s5    !#-F< 
;F344444r   c                 @    | j                             ddi f           d S )Nr1   r/   r    r   s    r   r1   zRecordingPointPen.endPath   s%    
9b"-.....r   Fc                 V    |||d<   | j                             d||||f|f           d S )NrF   addPointr    )r   ptsegmentTypesmoothnamerF   rH   s          r   rK   zRecordingPointPen.addPoint   s@     !#-F< 
:K'FOPPPPPr   c                 R    |||d<   | j                             d||f|f           d S )NrF   r3   r    )r   baseGlyphNamer5   rF   rH   s        r   r3   zRecordingPointPen.addComponent   s:    !#-F< 
>M>+JFSTTTTTr   c                 T    |||d<   | j                             d|||f|f           d S )NrF   r7   r    )r   rQ   r5   r8   rF   rH   s         r   r7   z!RecordingPointPen.addVarComponent   sI     !#-F< 
 I6R	
 	
 	
 	
 	
r   c                 N    | j         D ]\  }}} t          ||          |i | d S r   )r   r   )r   pointPenr   argsrH   s        r   r:   zRecordingPointPen.replay   sF    &*j 	9 	9"HdF'GHh''88888	9 	9r   r   )NFNN)r;   r<   r=   r>   r   rG   r1   rK   r3   r7   r:   
drawPointsr/   r   r   r   r      s         2  5 5 5 5
/ / / IMQ Q Q QU U U U CG
 
 
 
9 9 9 JJJr   r   c                       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', (), {})]}
    FNrA   r/   r   r   r
   r
      s%        T Tn "r   r
         ?c              #     K   t          |           t          |          k    r.t          dt          |           t          |          fz            t          | |          D ]]\  \  }}\  }}||k    rt          d|d|          |dk    rt          d          fdt          ||          D             }||fV  ^d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: z, r3   zCannot interpolate componentsc                 N    g | ]!\  \  }}\  }}|||z
  z  z   |||z
  z  z   f"S r/   r/   ).0x1y1x2y2factors        r   
<listcomp>z"lerpRecordings.<locals>.<listcomp>@  sV       &HRhr2 rBw&(("R6/A*AB  r   N)len
ValueErrorzip)
recording1
recording2r`   op1args1op2args2mid_argss     `     r   r   r   +  s      :#j//))+s:J.PP
 
 	
 '**j&A&A 
 
"elsE#::*SSIJJJ.  <===   *-eU*;*;  H Ho
 
r   __main__)r   r   )r   d   )2   K   )<   rn   )rn      )pprintN)rX   )r>   fontTools.pens.basePenr   r   fontTools.pens.pointPenr   r   __all__r   r   r	   r   r
   r   r;   r   r   r%   r,   r.   rr   r   r/   r   r   <module>rv      s   @ @ > > > > > > > > I I I I I I I I  	* 	* 	*6 6 6 6 6; 6 6 6r6" 6" 6" 6" 6"nl 6" 6" 6"r> > > > >( > > >BX" X" X" X" X"#68I X" X" X"v   8 z
,..CJJvJJxKK(H---MMOOO
F39 r   