
    jke?                    ~   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZmZmZ ddlmZmZ dd	lmZ dd
lmZmZmZmZ ddlmZmZ ddlm Z  ddl!m"Z" ddl#m$Z$ ddl#m%Z% ddl&Z&ddl'Z'ddl(Z(ddl)Z)ddl*Z*ddl+Z+ddlm,Z, ddl-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8  e)jr                  e:      Z;djy                   ejz                  d      dd       ZdZ> G d de$jH                        Z? edd      Z@dZAdZBdZCd ZDd!ZEd"ZFd#ZGd$ZHd%ZIeBeHz   eIz   ZJddeFdeCeFz  deCd&eGdeDeGz  deDd&iZKd' ZLd( ZMd) ZNd* ZOd+ ZPdZQdZRd ZSd!ZTd"ZUd#ZVd$ZWd%ZXd,ZYd-ZZd.Z[d/Z\d0Z] ed1g d2      Z^ G d3 d4e_      Z` e4e j                  e5      Zbd6ecd7ecd8ecd9edfd:Zed;e`d9e8ef   fd<Zg G d= d>e_      Zh G d? d@e2      Zi edAg dB      Zj ejeij                  ddd       ejeij                  ddd       ejeij                  dCdDd       ejeij                  dEdd       ejeij                  dEdd       ejeij                  dCdFd       ejeij                  dCdDd       ejeij                  ddd       ejeij                  ddd      dG	Zt G dH dIe_      Zu G dJ dKe_      Zve:dLk(  r4ddlwZwddl&Z& e&j                   ewj                         j                         yy)Mz6_g_l_y_f.py -- Converter classes for the 'glyf' table.    )
namedtuple)sstruct)ttLib)version)DecomposedTransform)tostrsafeEvalpad)updateBoundspointInRect)calcQuadraticBounds)fixedToFloatfloatToFixedfloatToFixedToStrstrToFixedToFloat)noRoundotRound)Vector)Number   )DefaultTable)	ttProgramN)	xmlWriter)userNameToFileName)deprecateFunction)IntFlag)partial)SimpleNamespace)Set.   c                      e Zd ZdZdgZdZd Zd"dZd Zd"dZ	d Z
d	 Zd
 Zd Zd Zd Zd Zd ZeZd#dZd Zd Zd Zd Zd#dZ	 d#eddZd#dZd Z ede      d#d       Z ede      d#d       Z  ed e      d!        Z!y)$table__g_l_y_fa  Glyph Data Table

    This class represents the `glyf <https://docs.microsoft.com/en-us/typography/opentype/spec/glyf>`_
    table, which contains outlines for glyphs in TrueType format. In many cases,
    it is easier to access and manipulate glyph outlines through the ``GlyphSet``
    object returned from :py:meth:`fontTools.ttLib.ttFont.getGlyphSet`::

                    >> from fontTools.pens.boundsPen import BoundsPen
                    >> glyphset = font.getGlyphSet()
                    >> bp = BoundsPen(glyphset)
                    >> glyphset["A"].draw(bp)
                    >> bp.bounds
                    (19, 0, 633, 716)

    However, this class can be used for low-level access to the ``glyf`` table data.
    Objects of this class support dictionary-like access, mapping glyph names to
    :py:class:`Glyph` objects::

                    >> glyf = font["glyf"]
                    >> len(glyf["Aacute"].components)
                    2

    Note that when adding glyphs to the font via low-level access to the ``glyf``
    table, the new glyphs must also be added to the ``hmtx``/``vmtx`` table::

                    >> font["glyf"]["divisionslash"] = Glyph()
                    >> font["hmtx"]["divisionslash"] = (640, 0)

    fvarr   c                    d|v r'|d   j                   D cg c]  }|j                   c}ng | _        |d   }t        |d         }d}d}i | _        |j                         x| _        }i | _        t        dt        |      dz
        D ]`  }		 ||	   }
t        ||	dz            }||| }t        |      ||z
  k7  rt        j                  d      t        |      }|| j                  |
<   |}b t        |      |z
  dk\  r t        j                  d|t        |             |rt        j                  d	|       |j                   d
u r| j#                          y y c c}w # t        $ r |dz   }d|	z  }
Y w xY w)Nr$   locar   r   zttxautoglyph%sznot enough 'glyf' table data   z:too much 'glyf' table data: expected %d, received %d bytesz%s glyphs have no nameF)axesaxisTagaxisTagsintglyphsgetGlyphOrder
glyphOrder_reverseGlyphOrderrangelen
IndexErrorr   
TTLibErrorGlyphlogwarninglazyensureDecompiled)selfdatattFontaxisr&   posnextPosnonamer.   i	glyphName	glyphdataglyphs                A/usr/lib/python3/dist-packages/fontTools/ttLib/tables/_g_l_y_f.py	decompileztable__g_l_y_f.decompile_   s   >D>NfVn&9&9:dT\\:TV 	 f~$q'l'-';';'==*"$q#d)a-( 	A1&qM	 $q1u+&GS)I9~'C-0&&'EFF)$E%*DKK	"C	 t9w!#KKLD	
 KK0&9;;%!!#  = ;  1!,q0	1s   EEE.-E.c                 d    | j                   j                         D ]  }|j                  |         y N)r,   valuesexpand)r9   recurserC   s      rD   r8   ztable__g_l_y_f.ensureDecompiled   s,     [['') 	ELL	    c                    d|v r'|d   j                   D cg c]  }|j                   c}ng | _        t        | d      s|j	                         | _        | j                  }|dv sJ g }d}g }|j                  }t               }| j
                  D ]g  }	| j                  |	   }
|
j                  | ||      }|dkD  rt        ||      }|j                  |       |t        |      z   }|j                  |       i |j                  |       |dk(  r|dk  rt        |      D cg c]  \  }}t        |      d	z  dk(  s| }}}|r[|t        |      z   dk  rJ|D ]  }||xx   d
z  cc<    d}t        |      D ]  \  }}|||<   |t        |      z  } ||t        |      <   dj                  |      }d|v r|d   j                  |       d|v rt        | j                        |d   _        |sd
}|S c c}w c c}}w )Nr$   r.   )r   r   r!   r'   r   
boundsDoner   )sizei   r!       rK   r&   maxp)r(   r)   r*   hasattrr-   r.   paddingrecalcBBoxessetr,   compiler
   appendr1   	enumeratejoin	numGlyphs)r9   r;   r<   rS   	locationscurrentLocationdataListrT   rN   rA   rC   	glyphDatar@   indicesr:   s                  rD   rV   ztable__g_l_y_f.compile   s   >D>NfVn&9&9:dT\\:TV 	 t\*$224DO,,,&&&	**U
 	'IKK	*EdLZPI{	8	_--I>OOOI&	' 	)a<Og5 '0&9"aS^a=OST=TG  ?S\9GC  )AQK5(K)"#$-h$7 6LAy#2IaL#s9~5O6 ,;	#h-(xx!V6Ny)V'*4;;'7F6N$
 Da ;0s   G/!G4;G4c           
      "   d}|j                         }|sA|j                          |j                  |       |j                          |j                          t        |      }|r@t        j
                  j                  |j                  j                        \  }}t               }	|D ]g  }
| j                  |
      }|t        j                  d|
       .|j                  r|rt        t        |
d      	dz         }|	j!                  |j#                                t%        j&                  ||j(                  |j*                        }|j-                  dt.               |j                          |j-                  d	       |j                          |j                  |       |j                          |j1                  d
t        j
                  j3                  |             n|}|j-                  d
d|
fd|j4                  fd|j6                  fd|j8                  fd|j:                  fg       |j                          |j=                  ||       |j?                  d
       |j                          |r|j?                  d	       |j                          |j?                  d       |j                          |jA                          n6|j1                  d
|
       |j                  d       |s|j                          |j                          j y )NzJThe xMin, yMin, xMax and yMax values
will be recalculated by the compiler.z'glyph '%s' does not exist in glyf tablezutf-8r    )prefixsuffix)idlefunc
newlinestrr;   )ttLibVersionglyfTTGlyph)srcnamexMinyMinxMaxyMax)ri   zcontains no outline data)!getGlyphNamesnewlinecommentr1   ospathsplitextfileri   rU   getr5   r6   numberOfContoursr   r   addlowerr   	XMLWriterrc   rd   begintagr   	simpletagbasenamerj   rk   rl   rm   toXMLendtagclose)r9   writerr;   splitGlyphsnotice
glyphNamesrZ   rr   extexistingGlyphFilesrA   rC   	glyphPathglyphWriters                 rD   r}   ztable__g_l_y_f.toXML   s   4 	 ))+
NNNN6"NNNN
O	(()9)9:ID#!$# 5	IHHY'E}EyQ%% 2i1*#cz"	!I '**9??+<="+"5"5!!'#)#4#4#K
  (((H'')((0'')''/'')$$YBGG4D4DY4O$P"(K$$+,,,,	 ##%K0""9-##%&&v.'')&&x0'')%%'   ;9:"NN$NNk5	rK   c                    |dk7  ry t        | d      si | _        t        | d      s|j                         | _        |d   }t        j                  d|       t               }dD ](  }t        ||t        |j                  |d                   * || j                  |<   |D ]-  }t        |t              s|\  }}}|j                  ||||       / |j                  s|j                  | d       y y )	Nrg   r,   r.   ri   zunpacking glyph '%s')rj   rk   rl   rm   0r   )rR   r,   r-   r.   r5   debugr4   setattrr	   ru   
isinstancetuplefromXMLrT   compact)	r9   ri   attrscontentr;   rA   rC   attrelements	            rD   r   ztable__g_l_y_f.fromXML  s    9tX&DKt\*$224DO&M			()44 	ADE4%))D#*>!?@	A!&I 	8Ggu-#* D%MM$w7		8
 ""MM$" #rK   c                      || _         i | _        y)znSets the glyph order

        Args:
                glyphOrder ([str]): List of glyph names in order.
        N)r.   r/   )r9   r.   s     rD   setGlyphOrderztable__g_l_y_f.setGlyphOrder  s     %"$rK   c                      | j                   |   S )zReturns the name for the glyph with the given ID.

        Raises a ``KeyError`` if the glyph name is not found in the font.
        )r.   )r9   glyphIDs     rD   getGlyphNameztable__g_l_y_f.getGlyphName   s    
 w''rK   c                 Z    i x| _         }t        | j                        D ]
  \  }}|||<    y rG   )r/   rX   r.   )r9   dr   rA   s       rD   _buildReverseGlyphOrderDictz*table__g_l_y_f._buildReverseGlyphOrderDict'  s5    &((!"+DOO"< 	#GY"AiL	#rK   c                     | j                   }t        | di       j                  |      }||t        |      k\  s||   |k7  r+| j	                          | j
                  j                  |      }|t        |      |S )zReturns the ID of the glyph with the given name.

        Raises a ``ValueError`` if the glyph is not found in the font.
        r/   )r.   getattrru   r1   r   r/   
ValueError)r9   rA   r.   ids       rD   
getGlyphIDztable__g_l_y_f.getGlyphID,  sy    
 __
T/488C:s:.*R.I2M,,.((,,Y7B:Y''	rK   c                 b    | j                   j                         D ]  }|j                           y)zmRemoves TrueType hints from all glyphs in the glyphset.

        See :py:meth:`Glyph.removeHinting`.
        N)r,   rH   removeHinting)r9   rC   s     rD   r   ztable__g_l_y_f.removeHinting:  s,    
 [['') 	"E!	"rK   c                 6    | j                   j                         S rG   )r,   keysr9   s    rD   r   ztable__g_l_y_f.keysB  s    {{!!rK   c                     || j                   v S rG   )r,   r9   rA   s     rD   has_keyztable__g_l_y_f.has_keyE  s    DKK''rK   Nc                 d    | j                   j                  ||      }||j                  |        |S rG   )r,   ru   rI   )r9   rA   defaultrC   s       rD   ru   ztable__g_l_y_f.getJ  s-    	73LLrK   c                 F    | j                   |   }|j                  |        |S rG   )r,   rI   r9   rA   rC   s      rD   __getitem__ztable__g_l_y_f.__getitem__P  s!    I&TrK   c                 v    || j                   |<   || j                  vr| j                  j                  |       y y rG   )r,   r.   rW   r   s      rD   __setitem__ztable__g_l_y_f.__setitem__U  s3    !&IDOO+OO""9- ,rK   c                 T    | j                   |= | j                  j                  |       y rG   )r,   r.   remover   s     rD   __delitem__ztable__g_l_y_f.__delitem__Z  s     KK	"y)rK   c                     t        | j                        t        | j                        k(  sJ t        | j                        S rG   )r1   r.   r,   r   s    rD   __len__ztable__g_l_y_f.__len__^  s1    4??#s4;;'77774;;rK   c                     | |   }t        |d      s|j                  |        ||   \  }}|j                  |z
  }||z   }|r||   \  }	}
|
|j                  z   }||	z
  }ndx}}|df|dfd|fd|fgS )a+  Compute the four "phantom points" for the given glyph from its bounding box
        and the horizontal and vertical advance widths and sidebearings stored in the
        ttFont's "hmtx" and "vmtx" tables.

        'hMetrics' should be ttFont['hmtx'].metrics.

        'vMetrics' should be ttFont['vmtx'].metrics if there is "vmtx" or None otherwise.
        If there is no vMetrics passed in, vertical phantom points are set to the zero coordinate.

        https://docs.microsoft.com/en-us/typography/opentype/spec/tt_instructing_glyphs#phantoms
        rj   r   )rR   recalcBoundsrj   rm   )r9   rA   hMetricsvMetricsrC   horizontalAdvanceWidthleftSideBearing	leftSideX
rightSideXverticalAdvanceWidthtopSideBearingtopSideYbottomSideYs                rD   _getPhantomPointsz table__g_l_y_f._getPhantomPointsb  s     Yuf%t$2:92E/JJ0	!77
3;I3F0 .%

2H"%99K%&&K( NOM	
 	
rK   roundc                >   | j                  |      }|y|j                         rt        |j                  D cg c]  }t	        |dd      t	        |dd      f c}      }t        |j                  t        t        t        |j                                    d|j                  D cg c]  }|j                  t	        |dd      f c}      }n|j                         rg }g }|j                  D ]7  }	|	j                         \  }
}|j                  |
       |j                  |       9 t        |      }t        |j                  t        t        t        |                  d|j                  D cg c]  }|j                  t	        |dd      f c}      }n>|j                  |       \  }}}|j                         }t        |j                  ||d      }| j!                  |||      }|j                  |       |j#                  |       ||fS c c}w c c}w c c}w )	a  Return glyph coordinates and controls as expected by "gvar" table.

        The coordinates includes four "phantom points" for the glyph metrics,
        as mandated by the "gvar" spec.

        The glyph controls is a namedtuple with the following attributes:
                - numberOfContours: -1 for composite glyphs.
                - endPts: list of indices of end points for each contour in simple
                glyphs, or component indices in composite glyphs (used for IUP
                optimization).
                - flags: array of contour point flags for simple glyphs (None for
                composite glyphs).
                - components: list of base glyph names (str) for each component in
                composite glyphs (None for simple glyphs).

        The "hMetrics" and vMetrics are used to compute the "phantom points" (see
        the "_getPhantomPoints" method).

        Return None if the requested glyphName is not present.
        Nxr   y	transform)rv   endPtsflags
componentsr   r   )ru   isCompositeGlyphCoordinatesr   r   _GlyphControlsrv   listr0   r1   rA   isVarCompositegetCoordinatesAndControlsextendgetCoordinatescopyr   toInt)r9   rA   r   r   r   rC   ccoordscontrols	componentcomponentCoordscomponentControlsr   r   phantomPointss                  rD   _getCoordinatesAndControlsz)table__g_l_y_f._getCoordinatesAndControls  s   . #=%CHCSCSTa'!S!$gaa&89TF &!&!7!7E#e&6&6"789 #-- [['![$"?@	H !!#FH"-- 3	 779#%o. 123 &f-F%!&!7!7E#f+./FKFVFVABQ[['!Wd";<	H %*$8$8$>!FFE[[]F%!&!7!7	H ..y(HMm$5!x_ U.s   !H% H/ Hc                 p   | |   }t        |      dk\  sJ |d   d   }|d   d   }|d   d   }|d   d   }	|dd }|j                         r^t        |      t        |j                        k(  sJ t        ||j                        D ]!  \  }
}t	        |d	      s|
\  |_        |_        # n|j                         r&|j                  D ]  }|j                  |      } |rTJ |j                  dk(  rt        |      dk(  s5J t        |      t        |j                        k(  sJ t        |      |_
        |j                  | t               
       t        ||z
        }|dk  rd}t        |j                  |z
        }||f||<   |5t        ||	z
        }|dk  rd}t        ||j                   z
        }||f||<   yy)a(  Set coordinates and metrics for the given glyph.

        "coord" is an array of GlyphCoordinates which must include the "phantom
        points" as the last four coordinates.

        Both the horizontal/vertical advances and left/top sidebearings in "hmtx"
        and "vmtx" tables (if any) are updated from four phantom points and
        the glyph's bounding boxes.

        The "hMetrics" and vMetrics are used to propagate "phantom points"
        into "hmtx" and "vmtx" tables if desired.  (see the "_getPhantomPoints"
        method).
        r'   r   r   Nr   rM   )r1   r   r   ziprR   r   r   r   setCoordinatesrv   coordinatesr   r   rU   r   rj   rm   )r9   rA   coordr   r   rC   r   r   r   r   pcompr   r   r   r   s                   rD   _setCoordinatesztable__g_l_y_f._setCoordinates  s    Y 5zQ"IaL	2Yq\
9Q<Bilcr
u:U%5%5!6666ue&6&67 '44%%&NDFDF' !!#(( 3++E239##q(u:?"?u:U%6%6!7777 0 7E4CE2!(i)?!@!A% &'"!%**y"894oE#*8k+A#B #a''($$X

%:;N"6"FHY  rK   c                    t        |j                  d      dd      }|h|d   j                  }t        |j                  d      dd      }|||}n|}| |   }|j                  |        t	        ||j
                  z
        }|||fi}|S )zThis method is wrong and deprecated.
        For rationale see:
        https://github.com/fonttools/fonttools/pull/2266/files#r613569473
        vmtxmetricsNheadhheaascent)r   ru   
unitsPerEmr   r   rm   )	r9   rA   r;   defaultVerticalOriginr   r   r   rC   r   s	            rD   _synthesizeVMetricsz"table__g_l_y_f._synthesizeVMetrics  s    
 6::f-y$?#)&>#<#< vzz&18TBH(44H3HOEt$$X

%:;N!$8.#IJHrK   zuse '_getPhantomPoints' instead)categoryc                 l    |d   j                   }| j                  |||      }| j                  |||      S )zkOld public name for self._getPhantomPoints().
        See: https://github.com/fonttools/fonttools/pull/2266hmtx)r   r   r   r9   rA   r;   r   r   r   s         rD   getPhantomPointsztable__g_l_y_f.getPhantomPoints   s=     &>))++Iv?TU%%i8DDrK   z(use '_getCoordinatesAndControls' insteadc                 l    |d   j                   }| j                  |||      }| j                  |||      S )ztOld public name for self._getCoordinatesAndControls().
        See: https://github.com/fonttools/fonttools/pull/2266r   )r   r   r   r   s         rD   r   z(table__g_l_y_f.getCoordinatesAndControls(  s=     &>))++Iv?TU..y(HMMrK   zuse '_setCoordinates' insteadc                     |d   j                   }t        |j                  d      dd      }| j                  |||       y)ziOld public name for self._setCoordinates().
        See: https://github.com/fonttools/fonttools/pull/2266r   r   r   N)r   r   ru   r   )r9   rA   r;   r   r   s        rD   r   ztable__g_l_y_f.setCoordinates2  s<     &>))6::f-y$?Y(;rK   FrG   )"__name__
__module____qualname____doc__dependenciesrS   rE   r8   rV   r}   r   r   r   r   r   r   r   r   __contains__ru   r   r   r   r   r   r   r   r   r   r   DeprecationWarningr   r   r    rK   rD   r#   r#   8   s    < 8L G!$F2hDL#*%(#
""( L
.
*  
F -1K ;BK Z7Gv( 8CUVE WE 2=ONN 6AST< U<rK   r#   r   z(numberOfContours endPts flags componentsz\
		>	# big endian
		numberOfContours:	h
		xMin:				h
		yMin:				h
		xMax:				h
		yMax:				h
r'             @      r   c                 *   |rt         nd}d}| dk(  r
|t        z  }n0d| cxk  rdk  r n n|t        z  }| dkD  r	|t        z  }|dz  }n|dz  }|dk(  r|t        z  }||fS d|cxk  rdk  r#n n |t        z  }|dkD  r	|t        z  }|dz  }||fS |dz  }||fS )zFor a given x,y delta pair, returns the flag that packs this pair
    most efficiently, as well as the number of byte cost of such flag.r      r   r!   )flagOnCurve	flagXsame
flagXShort	flagYsame
flagYShort)r   r   onCurveflagcosts        rD   flagBestr  a  s     ";qDDAvi		c	j q5)#D		Avi : 
	c	j q5)#D	 : 		:rK   c                 n    t         | |z     }t         ||z     }||k(  xs t        |      t        |      kD  S rG   )_flagSignBytesabs)newFlagoldFlagmasknewBytesoldBytess        rD   flagFitsr  ~  s;    gn-Hgn-Hx@3x=3x=#@@rK   c                     |t         z  | t         z  k(  xr2 t        | |t        t        z        xr t        | |t        t
        z        S rG   )r
  r  r  r  r  r  )r  r  s     rD   flagSupportsr    sE    	;	Gk$9: 	?Wgy:'=>	?Wgy:'=>rK   c                     t         | |z     }|dk(  r|j                  |       y |dk(  r|j                  |        y |dk(  r&|j                  t        j                  d|             y y )Nr   r   r!   >h)r  rW   r   structpack)r  r  r   
coordBytes	byteCounts        rD   flagEncodeCoordr$    sa    td{+IA~% 	b5&!	a&++dE23 
rK   c                 h    t        | t        t        z  ||       t        | t        t        z  ||       y rG   )r$  r  r  r  r  )r  r   r   xBytesyBytess        rD   flagEncodeCoordsr(    s(    D)j0!V<D)j0!V<rK                  CompositeMaxpValues)nPoints	nContoursmaxComponentDepthc                       e Zd ZdZd!dZd"dZd Zd"dddZd Zd	 Z	d#d
Z
d Zd Zd Zd Zd$dZd Zd Zd Zd Zd ZdddZdddZd Zd Zd Zd Zd%dZd Zd$dZd$dZd Zd  Z y)&r4   a  This class represents an individual TrueType glyph.

    TrueType glyph objects come in two flavours: simple and composite. Simple
    glyph objects contain contours, represented via the ``.coordinates``,
    ``.flags``, ``.numberOfContours``, and ``.endPtsOfContours`` attributes;
    composite glyphs contain components, available through the ``.components``
    attributes.

    Because the ``.coordinates`` attribute (and other simple glyph attributes mentioned
    above) is only set on simple glyphs and the ``.components`` attribute is only
    set on composite glyphs, it is necessary to use the :py:meth:`isComposite`
    method to test whether a glyph is simple or composite before attempting to
    access its data.

    For a composite glyph, the components can also be accessed via array-like access::

            >> assert(font["glyf"]["Aacute"].isComposite())
            >> font["glyf"]["Aacute"][0]
            <fontTools.ttLib.tables._g_l_y_f.GlyphComponent at 0x1027b2ee0>

    c                 &    |sd| _         y || _        y Nr   )rv   r:   )r9   r:   s     rD   __init__zGlyph.__init__  s    $%D!	rK   c                 j    | j                  ||      }| j                  j                          || _        y rG   )rV   __dict__clearr:   )r9   	glyfTablerT   r:   s       rD   r   zGlyph.compact  s)    ||I|4	rK   c                 l   t        | d      sy | j                  s
| `d| _        y t        j                  t
        | j                  |       \  }}| `| j                  dk(  ry | j                         r| j                  ||       y | j                         r| j                  ||       y | j                  |       y )Nr:   r   )rR   r:   rv   r   unpack2glyphHeaderFormatr   decompileComponentsr   decompileVarComponentsdecompileCoordinates)r9   r9  dummyr:   s       rD   rI   zGlyph.expand  s    tV$yy	$%D!oo&7DItI   A%$$T95  "''i8%%d+rK   NrM   c                   t        | d      r |r| j                  |       n| j                  S | j                  dk(  ry|r| j	                  ||       t        j                  t        |       }| j                         r|| j                  |      z   }|S | j                         r|| j                  |      z   }|S || j                         z   }|S )Nr:   r   rK   rM   )rR   rI   r:   rv   r   r   r!  r<  r   compileComponentsr   compileVarComponentscompileCoordinates)r9   r9  rT   rN   r:   s        rD   rV   zGlyph.compile  s    4 I&yy   A%iJ?||-t4$00;;D
 	   "$33I>>D  $1133DrK   c                    | j                         r1| j                  D ]  }|j                  ||        t        | d      }n| j	                         r'| j                  D ]  }|j                  ||        d}nQd}t        | j                        D ]'  }|j                  d       |j                          t        || j                  |   dz         D ]  }d| j                  |   d   fd| j                  |   d   fd| j                  |   t        z  fg}| j                  |   t        z  r|j                  d	       | j                  |   t        z  r|j                  d
       |j!                  d|       |j                           | j                  |   dz   }|j#                  d       |j                          * | j                  dkD  }|r}| j$                  rO|j                  d       |j                          | j$                  j                  ||       |j#                  d       n|j!                  d       |j                          y y )NprogramFr   contourr   r   r   on)overlapr   )cubicr   ptinstructions)r   r   r}   rR   r   r0   rv   rz   ro   endPtsOfContoursr   r   r
  flagOverlapSimplerW   	flagCubicr{   r~   rF  )	r9   r   r;   compohaveInstructionslastr@   jr   s	            rD   r}   zGlyph.toXML  s    ,FF+,&tY7  " ,FF+,$D4001 !	* tT%:%:1%=%AB %Ad..q1!45d..q1!45tzz!}{:;E
 zz!}'88^4zz!}y0\2$$T51NN$% ,,Q/!3i( %!&  $44q8||/ ""662n-  0NN rK   c                    |dk(  r| j                   dk  rt        j                  d      | j                   dz   | _         t               }t	               }|D ]  }t        |t              s|\  }}}|dk7  r |j                  t        |d         t        |d         f       t        t        |d               }d	|v r t        t        |d	               r	|t        z  }d
|v r t        t        |d
               r	|t        z  }|j                  |        t        | d      s#|| _        || _        t        |      dz
  g| _        y | j                  j#                  |       | j                  j#                  |       | j                   j                  t        | j                        dz
         y |dk(  rx| j                   dkD  rt        j                  d      d| _         t        | d      sg | _        t'               }	| j$                  j                  |	       |	j)                  ||||       y |dk(  rx| j                   dkD  rt        j                  d      d| _         t        | d      sg | _        t+               }	| j$                  j                  |	       |	j)                  ||||       y |dk(  rVt-        j.                         | _        |D ]7  }t        |t              s|\  }}}| j0                  j)                  ||||       9 y y )NrG  r   z*can't mix composites and contours in glyphr   rK  r   r   rH  rI  rJ  r   r   r   r   varComponentr   rL  )rv   r   r3   r   	bytearrayr   r   rW   r	   boolrN  rO  rR   r   r   r1   rM  r   r   GlyphComponentr   GlyphVarComponentr   ProgramrF  )
r9   ri   r   r   r;   r   r   r   r  r   s
             rD   r   zGlyph.fromXML(  s   9$$q(&&'STT$($9$9A$=D!*,KKE" #!'51'.$eW4<""HU3Z$8(5::N#OPHU4[12%$xi8H/I*J--De#XeGn-E(FI%DT"# 4/#. "
),[)9A)=(>%  ''4

!!%(%%,,S1A1A-BQ-FG[ $$q(&&'STT$&D!4."$&(IOO""9-dE7F;^#$$q(&&'STT$&D!4."$)+IOO""9-dE7F;^#$,,.DL" C!'51'.$eW$$T5'6B	C $rK   c                 p   | j                         s| j                         sJ d}d}|}| j                  D ]s  }||j                     }|j                  dk(  r"|j                  dkD  r|j                         \  }}	n%|j                  ||dz         \  }}	}
t        ||
      }||z   }||	z   }u t        |||      S )Nr   r   )	r   r   r   rA   rv   getMaxpValuesgetCompositeMaxpValuesmaxr.  )r9   r9  r1  r0  r/  initialMaxComponentDepthrP  	baseGlyphnPnCcomponentDepths              rD   r]  zGlyph.getCompositeMaxpValues^  s    !T%8%8%:::	#4 __ 	'E!%//2I))Q.++a/"002B)2)I)I7!;*&B %((9>$J!lG!BI	' #7I7HIIrK   c                 x    | j                   dkD  sJ t        | j                        t        | j                        fS r4  )rv   r1   r   rM  r   s    rD   r\  zGlyph.getMaxpValuesr  s7    $$q(((4##$c$*?*?&@@@rK   c                    g | _         d}d}|rCt               }|j                  ||      \  }}}||z  }| j                   j                  |       |rC|rt	        j
                  d|d d       \  }|dd  }t        j                         | _        | j                  j                  |d |        ||d  }t        |      dk\  r t        j                  dt        |             y y y )Nr   r   r  r!   r'   zBtoo much glyph data at the end of composite glyph: %d excess bytes)r   rX  rE   rW   r   unpackr   rZ  rF  fromBytecoder1   r5   r6   )r9   r:   r9  morerQ  r   	haveInstrnumInstructionss           rD   r=  zGlyph.decompileComponentsv  s    &(I$-$7$7i$H!D)T/);OO""9-	 
 !'tT"1X!>_8D$,,.DLLL%%d+;O&<=()D4yA~XI  rK   c                     g | _         t        |      t        j                  k\  rUt               }|j	                  ||      }| j                   j                  |       t        |      t        j                  k\  rTy y rG   )r   r1   rY  MIN_SIZErE   rW   )r9   r:   r9  r   s       rD   r>  zGlyph.decompileVarComponents  s]    $i,555)+I&&tY7DOO""9- $i,555rK   c                 >   t        j                   d      }|j                  |d d| j                  z          t        j                  dk7  r|j                          |j                         | _        d| j                  z  }t        j                  d|||dz          \  }t        j                         | _        | j                  j                  ||dz   |dz   |z           |d|z   z  }| j                  d   dz   }| j                  |||      \  }}}t        j!                  |      x| _        }	d}
d}t%        |      D ]  }||   }|t&        z  r|t(        z  r||
   }n||
    }|
dz   }
n|t(        z  rd}n
||
   }|
dz   }
|t*        z  r|t,        z  r||   }n||    }|dz   }n|t,        z  rd}n
||   }|dz   }||f|	|<    |
t/        |      k(  sJ |t/        |      k(  sJ |	j1                          t%        t/        |            D ]  }||xx   t2        z  cc<    || _        y )NHr!   bigr  r   r   r   )array	frombytesrv   sys	byteorderbyteswaptolistrM  r   rf  r   rZ  rF  rg  decompileCoordinatesRawr   zerosr   r0   r  r  r  r  r1   relativeToAbsolute	keepFlagsr   )r9   r:   rM  r=   instructionLengthnCoordinatesr   xCoordinatesyCoordinatesr   xIndexyIndexr@   r  r   r   s                   rD   r?  zGlyph.decompileCoordinates  sS    ;;s+""4(C!d.C.C*C#DE==E!%%' 0 7 7 9$'''%}}T4cAg3FG	 ((*!!$sQwq;L1L"MNq$$$,,R014,0,H,H$-
)|\
 *:)?)?)MM;|$ 	$A8Dj )#$V,A%f--A!	! (!j )#$V,A%f--A!	! (!VKN5	$6 \****\****&&(s5z" 	"A!H	!H	"
rK   c                    t        |      }d}d}d}	 ||   }|dz  }d}	|t        z  r||   dz   }	|dz  }t        |	      D ]F  }
|t        z  r|dz   }n|t        z  s|dz   }|t
        z  r|dz   }n|t        z  s|dz   }|||<   |dz   }H ||k\  rn}||k(  sJ d       t        j                  |      }t        j                  |      }t        |      |z
  ||z   z
  dk\  r(t        j                  dt        |      |z
  ||z   z
         t        j                  |||||z          }t        j                  ||||z   ||z   |z          }|||fS )	N>r   r   Bhbad glyph flagsr'   z$too much glyph data: %d excess bytes)rV  
flagRepeatr0   r  r  r  r  r   calcsizer1   r5   r6   rf  )r9   r{  r:   r=   r   xFormatyFormatrS  r  repeatkxDataLenyDataLenr|  r}  s                  rD   rv  zGlyph.decompileCoordinatesRaw  s   ,' 9D1HCFj cQq6] 
*$%mG*%mG*$%mG*%mGaE
 L ' ( L 3"33 ??7+??7+t9s?h12a7KK6D	C8h#67 }}Wd3x.HI}}T#.3>H+DE
 lL00rK   c                 z   d}t        | j                        dz
  }d}d}t        t        | j                              D ]:  }||k(  rt        | d      }d}| j                  |   }||j	                  |||      z   }< |r?| j
                  j                         }|t        j                  dt        |            z   |z   }|S )NrK   r   r   rF  r  )	r1   r   r0   rR   rV   rF  getBytecoder   r!  )	r9   r9  r:   lastcomponentrh  rQ  r@   rP  rL  s	            rD   rB  zGlyph.compileComponents  s    DOO,q0s4??+, 	KAM!#*4#; OOA&E%--.>	JJD	K <<335L&++dC,=>>MDrK   c                 L    dj                  fd| j                  D              S )NrK   c              3   @   K   | ]  }|j                          y wrG   )rV   ).0r   r9  s     rD   	<genexpr>z-Glyph.compileVarComponents.<locals>.<genexpr>  s     F		),Fs   )rY   r   )r9   r9  s    `rD   rC  zGlyph.compileVarComponents  s    xxFdooFFFrK   c                    t        | j                        t        | j                        k(  sJ g }t        j                  d| j                        }t
        j                  dk7  r|j                          |j                  |j                                | j                  j                         }|j                  t        j                  dt        |                   |j                  |       | j                  j                         }|j                          |j!                          | j#                  | j                  |      }|j%                  |       dj'                  |      S )Nrn  ro  r  rK   )r1   r   r   rp  rM  rr  rs  rt  rW   tobytesrF  r  r   r!  r   r   absoluteToRelativecompileDeltasGreedyr   rY   )r9   r:   rM  rL  deltass        rD   rD  zGlyph.compileCoordinates	  s   4##$DJJ777 ;;sD,A,AB==E!%%'$,,./||//1FKKc,&789L!!!&&(!!# ))$**f= 	Fxx~rK   c                    t               }t               }t               }d }d}t        ||      D ]4  \  }\  }	}
|	dk(  r
|t        z  }n`d|	cxk  rdk  r0n n-|t        z  }|	dkD  r
|t        z  }n|	 }	|j	                  |	       n%|j                  t        j                  d|	             |
dk(  r
|t        z  }n`d|
cxk  rdk  r0n n-|t        z  }|
dkD  r
|t        z  }n|
 }
|j	                  |
       n%|j                  t        j                  d|
             ||k(  r3|dk7  r.|dz   }|dk(  r|j	                  |       n%|t        z  |d<   ||d<   nd}|j	                  |       |}7 |||fS )Nr   r  r	  r  r   r   r   )rV  r   r  r  rW   r   r   r!  r  r  r  )r9   r   r  compressedFlagscompressedXscompressedYslastflagr  r  r   r   s              rD   r  zGlyph.compileDeltasGreedy  s    $+ { {v. %	LD&1a Avi'!c!j(q5)+DA##A&##FKKa$89Avi'!c!j(q5)+DA##A&##FKKa$89xFcM!Q;#**40*.*;OB'*0OB'&&t,HK%	L  |<<rK   c           	         g }d }d}d}t        ||      D ]  \  }\  }}	t        ||	|      \  }}
|d|
z   z  }||||
f|dz   ||t        z  |
fg}|D ]c  \  }}}}
||
z   |dz   k  s|t        z  s|dk  s$t        ||      s1|dz  |t        z  k(  r	||dz   k(  rI|j	                  ||
z   ||dz   |
f       e |}t        |d       }|d   } g }|r|\  }}}}
|j	                  |       |r|j                          t               }t               }t               }t        |      }g }|D ]  }|dz	  |dz  }}|j	                  |       |t        z  r|dkD  sJ |j	                  |       n|dk(  sJ t        d|z         D ]0  }t        |      \  }}	t        |||	||       |j	                  |       2  	 t        |       t        d	      # t        $ r Y nw xY w|||fS )
Nr   r   i   r	  r)  c                     | d   S r4  r  )ts    rD   <lambda>z,Glyph.compileDeltasOptimal.<locals>.<lambda>m  s
    ad rK   )keyr  zinternal error)r   r  r  r  rW   minreverserV  iterr0   nextr(  	ExceptionStopIteration)r9   r   r  
candidates	bestTuplebestCostr  r  r   r   r"  newCandidateslastCost	lastTuplelastFlagr  r  r  r  r   ffrepeatCountr@   s                          rD   compileDeltasOptimalzGlyph.compileDeltasOptimalO  sU    
	v. 	$LD&1a'1d3D*J&H9dJ7Ay4*+<zJM >H 9)Xzz)X\9!J.!F*$Xt4 4z)"hl2 !((!J.	8c>:V 'JJN;I |H1	$4 09-D)T:LL  	#+ { {f 	 D $	4$;K""4(j "Q&&&{3"a'''1{?+  F|1 q!\<H		$ 	 	L,-- 		  |<<s   2G 	GGc                    | j                         r| j                  ||      ry	 | j                  |      \  }}}|j                         \  | _        | _        | _        | _        y# t        $ r Y yw xY w)a=  Recalculates the bounds of the glyph.

        Each glyph object stores its bounding box in the
        ``xMin``/``yMin``/``xMax``/``yMax`` attributes. These bounds must be
        recomputed when the ``coordinates`` change. The ``table__g_l_y_f`` bounds
        must be provided to resolve component bounds.
        rM   N)	r   tryRecalcBoundsCompositer   calcIntBoundsrj   rk   rl   rm   NotImplementedError)r9   r9  rN   r   r   r   s         rD   r   zGlyph.recalcBounds  sz     $"?"?* #@ #
 	$($7$7	$B!FFE9?9M9M9O6DIty$)TY" 		s   >A% %	A10A1c                   | j                   D ]d  }t        |d      st        |d      r yt        |j                        j	                         r$t        |j
                        j	                         rd y d}| j                   D ]  }|j                  }||   }|||vr&|j                  ||       ||j                  |       |j                  dk(  rP|j                  |j
                  }}t        ||j                  |z   |j                  |z   f      }t        ||j                  |z   |j                  |z   f      } |d}|\  | _        | _        | _        | _        y)	a=  Try recalculating the bounds of a composite glyph that has
        certain constrained properties. Namely, none of the components
        have a transform other than an integer translate, and none
        uses the anchor points.

        Each glyph object stores its bounding box in the
        ``xMin``/``yMin``/``xMax``/``yMax`` attributes. These bounds must be
        recomputed when the ``coordinates`` change. The ``table__g_l_y_f`` bounds
        must be provided to resolve component bounds.

        Return True if bounds were calculated, False otherwise.
        firstPtr   FNrM   r   r   r   r   r   T)r   rR   floatr   
is_integerr   rA   r   rw   rv   r   rj   rk   rl   rm   )	r9   r9  rN   rP  boundsrA   gr   r   s	            rD   r  zGlyph.tryRecalcBoundsComposite  s>    __ 	Eui(GE;,G>,,.eEGGn6O6O6Q		 __ 	DEI)$A!Yj%@yZ@)NN9-!!Q&77EGGqA!&166A:qvvz*BCF!&166A:qvvz*BCF	D  >!F5;2	49dirK   c                     t        | d      r7| j                  r)t        j                  d| j                  dd       d   dk(  S dS | j                  dk(  S )z#Test whether a glyph has componentsr:   r  Nr!   r   r   FrR   r:   r   rf  rv   r   s    rD   r   zGlyph.isComposite  N    4 BF))6==tyy!}5a8B>VQVV((B..rK   c                     t        | d      r7| j                  r)t        j                  d| j                  dd       d   dk(  S dS | j                  dk(  S )z,Test whether a glyph has variable componentsr:   r  Nr!   r   r   Fr  r   s    rD   r   zGlyph.isVarComposite  r  rK   c                    | j                   dkD  r#| j                  | j                  | j                  fS | j	                         rt               }t               }g }| j                  D ]  }||j                     }	 |j                  |      \  }}}	t        |      }t        |d      rgt        |d      r|j                  |j                         ||j                     \  }
}||j                      \  }}|
|z
  ||z
  f}|j#                  |       n|j$                  |j&                  f}t        |d      s|j#                  |       n|j                  t(        z  }|j                  t*        z  }|r|rJ |s	|st,        }n|}|r-|j#                  |       |j                  |j                         n,|j                  |j                         |j#                  |       t/        |      |j1                  fd|D               |j1                  |       |j1                  |	        |||fS | j3                         rt5        d      t               g t               fS # t        $ r# t        j                  d|j                  z        w xY w)a  Return the coordinates, end points and flags

        This method returns three values: A :py:class:`GlyphCoordinates` object,
        a list of the indexes of the final points of each contour (allowing you
        to split up the coordinates list into contours) and a list of flags.

        On simple glyphs, this method returns information from the glyph's own
        contours; on composite glyphs, it "flattens" all components recursively
        to return a list of coordinates representing all the components involved
        in the glyph.

        To interpret the flags for each point, see the "Simple Glyph Flags"
        section of the `glyf table specification <https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#simple-glyph-description>`.
        r   z3glyph '%s' contains a recursive component referencer  r   c              3   (   K   | ]	  }|z     y wrG   r  )r  eoffsets     rD   r  z'Glyph.getCoordinates.<locals>.<genexpr>  s      <V <s   z*use TTGlyphSet to draw VarComposite glyphs)rv   r   rM  r   r   r   rV  r   rA   r   RecursionErrorr   r3   rR   r   r  secondPt	translater   r   SCALED_COMPONENT_OFFSETUNSCALED_COMPONENT_OFFSETSCALE_COMPONENT_OFFSET_DEFAULTr1   r   r   r  )r9   r9  	allCoordsallFlags	allEndPtsrP  r  r   r   r   x1y1x2y2move	apple_wayms_wayscale_component_offsetr  s                     @rD   r   zGlyph.getCoordinates  sZ       1$##T%:%:DJJFF(*I {HI -'eoo.121A1A)1L.K /{;5), uk2#--eoo>&u}}5FB(8FB7BG+D))$/ !77EGG+D"5+6#--d3$)KK2I$I	!&/H!H$-&99 )V > 3 6?21'11$7'11%//B (11%//B'11$7Y   <V <<  -&[-'\ i11  "%&RSS#%r9;66] & **M//* s   ;I,Jc                    t        | d      r!| j                         r| j                  |       t        | d      sF| j                         s| j                         r$| j                  D cg c]  }|j
                   c}S g S | j                  r)t        j                  d| j                  dd       d   dk\  rg S | j                  }d}g }d}|rt        j                  d|||d	z          \  }}|d	z  }t        |      }|j                  |j                  t        |                   |t        z  r|d	z  }n|dz  }|t        z  r|dz  }n|t        z  r|d	z  }n|t        z  r|d
z  }|t         z  }|r|S c c}w )zReturns a list of names of component glyphs used in this glyph

        This method can be used on simple glyphs (in which case it returns an
        empty list) or composite glyphs.
        r:   r  Nr!   r   
   r   >HHr'   r  )rR   r   rI   r   r   rA   r:   r   rf  r+   rW   r   ARG_1_AND_2_ARE_WORDSWE_HAVE_A_SCALEWE_HAVE_AN_X_AND_Y_SCALEWE_HAVE_A_TWO_BY_TWOMORE_COMPONENTS)	r9   r9  r   r:   r@   r   rh  r   r   s	            rD   getComponentNameszGlyph.getComponentNames$  sg    4 T%8%8%:KK	"tV$!T%8%8%:-1__===	 yyFMM$		"1>qAQFIyy
#]]5$q1q5/BNE7FAJEi44S\BC,,QQ&Q11Q--Q?*D! $ ? >s   (E1c                    t        | d      sh|re| j                         rt        | d      r| `y| j                         r	 yt	        j
                         | _        | j                  j                  g        y| j                  syt        j                  d| j                  dd       d   }t        | j                        }d}|dk\  r|d|z  z  }||dz
     dz  ||d	z
     z  d	z   }||   dz  ||d	z      z  }|r%dx||<   ||d	z   <   |dz  }|r|d| |||z   d z   }d}n|d|z   z  }d}d}	 ||   }	|d	z   }d	}
|	t        z  r||   d	z   }
|d	z   }dx}}|	t        z  rd	}n|	t        z  sd}|	t        z  rd	}n|	t        z  sd}|||z   |
z  z  }||
z  }||k\  rnk||k(  sJ d       ||z  }|d| }|| _        y| j                         rd	}d}|r||   dz  ||d	z      z  }|r
|t          z  }|t         z  rd
}|dz	  ||dz   <   |dz  ||d	z   <   |dz  }t#        |      }|t$        z  r|dz  }n|dz  }|t&        z  r|dz  }n|t(        z  r|dz  }n|t*        z  r|dz  }|t,        z  }|r|r||   dz  ||d	z      z  }|d|z   z  }|d| }|| _        y| j                         r`d}t.        j0                  }t3        ||||z          |k\  r5t.        j5                  ||||z          }||z  }t3        ||||z          |k\  r5|d| }|| _        y)zRemove padding and, if requested, hinting, from a glyph.
        This works on both expanded and compacted glyphs, without
        expanding it.r:   rF  Nr  r!   r   r  r  r   Tr  Fr	  r'   )rR   r   rF  r   r   rZ  rg  r:   r   rf  rV  r  r  r  r  r  WE_HAVE_INSTRUCTIONSr+   r  r  r  r  r  rY  rl  r1   getSize)r9   remove_hintingnumContoursr:   r@   r{  instructionLenr"  rS  r  r  r&  r'  rh  we_have_instructionsr   rl  rO   s                     rD   trimz
Glyph.trimQ  s    tV$##%tY/ L  ((*
  $-#4#4#6DLLL--b1yymmD$))BQ-8;#![ A!!a%[A-a!e<AL"1gld1q5k9N())Q$q1u+Q!8d1~+=+?&@@D!"Q''JAAwE*$!!Wq[FAA"##*$F*F*$F*Fv&88
V$' ( $7&77$OA8DN 	M D#( aAa!e4!222E//+/(#qjQU#dlQUQE
00FAFA?*FA55FA11FA.+ , $"&q'Q,$q1u+!=Q''8D 	   "A(11Hd1q8|,-9(00a!h,1GHT	 d1q8|,-9 8D	rK   c                 (    | j                  d       y)z5Removes TrueType hinting instructions from the glyph.T)r  N)r  r   s    rD   r   zGlyph.removeHinting  s    			&rK   c                 8   | j                         r7| j                  D ]'  }|j                         \  }}|j                  ||       ) y| j	                  |      \  }}}	|r#|j                         }|j                  |df       d}
d }|D ]  }|dz   }||
| }|	|
| D cg c]  }t        |z   }}|	|
| D cg c]  }t        |z   }}|}
d|vrt        |      st        |      rJ t        |      }|rt        |      }|dz  dk(  sJ d       |d   }|d   } ||d   |d   z   dz         ||d   |d   z   dz        f}|j                  |       t        d|d      D ]\  }||   }||dz      }||dz   |k  r|dz   nd   } ||d   |d   z   dz         ||d   |d   z   dz        f}|j                  |||       ^ n|j                  d        |j                   |  n|j#                  d      dz   }||d |d| z   }||d |d| z   }||d |d| z   }|j                  |d          |rK|j#                  d      dz   }|dk(  r$t        |      dkD  r|j%                  |d          n|d|dz
   D cg c]  }| }}t        |      st        |      rJ t        |      }|rt        |      sJ d	       |}|d
k\  sJ d       |dz
  dz  dk(  sJ d       t        d|d
z
  d      D ]T  }||   }||dz      }||dz      } ||d   |d   z   dz         ||d   |d   z   dz        f}|}|j                  |||       V  |j                  ||d
z
  |   n |j                   |d|   ||d }||d }||d }|rK|j'                           yc c}w c c}w c c}w )ah  Draws the glyph using the supplied pen object.

        Arguments:
                pen: An object conforming to the pen protocol.
                glyfTable: A :py:class:`table__g_l_y_f` object, to resolve components.
                offset (int): A horizontal offset. If provided, all coordinates are
                        translated by this offset.
        Nr   c                 8    | t        |       k(  rt        |       S | S rG   )r+   )vs    rD   r  zGlyph.draw.<locals>.<lambda>  s    qCF{SV  rK   r   r!   z(Odd number of cubic off-curves undefinedr         ?z+Mixed cubic and quadratic segment undefined   z,At least two cubic off-curve points required)r   r   getComponentInfoaddComponentr   r   r  r
  rO  allanyr1   moveTor0   curveTorW   qCurveToindexlineTo	closePath)r9   penr9  r  r   rA   r   r   r   r   startmaybeIntendrG  fcFlagscuFlagsrJ  countlp0r@   p1p2p4p3firstOnCurvenextOnCurve
cubicFlagslastOnCurves                                 rD   drawz
Glyph.draw  s    !__ 7	'0'A'A'C$	9  I67 %)%8%8%C"VU%**,K!!61+.9 O	C'C!%,G/4U3/?@!kAo@F@.3E#.>?y1}?G?E7|3w<77GLE 19>U+UU>A
A"AaD1Q4K3#671Q4!A$;RUBU9VWBJJrN"1eQ/ 0$QZ$QU^$a!eemQUC$bebems%:;$bebems%:; BB/0 NN4( CLL'*
  &||A2!,-07=L3II.1FF!,-07=L3II

72;'"(,,q/A"5K"a' w<!+JJwqz2189J;?1K%LAa%L
%L":c*oEE #J #& *$ MLM $ %0E %
NMN * !&	 !$"%&$' S(RS $' &+1eai%; 	8%,QZ%,QU^%,QU^$,bebems-B$C$,bebems-B$C&" /1 #BB 7	8 (CKKU)CD(CLL',;*?@%kl3G#KL1F%kl3GM N MMO_O	 A?X &Ms   N7N5	Nc                 f   | j                         r7| j                  D ]'  }|j                         \  }}|j                  ||       ) y| j	                  |      \  }}}	|r#|j                         }|j                  |df       d}
|D ]  }|dz   }||
| }|	|
| }|}
|j                          |d   t        z  rd}n|d   t        z  rd}nd}t        |      D ]H  \  }}||   t        z  r|j                  ||       d}(|j                  |       ||   t        z  rdnd}J |j                           y)	zDraw the glyph using the supplied pointPen. As opposed to Glyph.draw(),
        this will not change the point indices.
        Nr   r   r   linecurveqcurve)segmentType)r   r   r  r  r   r   r  	beginPathr
  rO  rX   addPointendPath)r9   r  r9  r  r   rA   r   r   r   r   r  r  rG  r  r  r@   rK  s                    rD   
drawPointszGlyph.drawPoints"  sU   
 !__ 7	'0'A'A'C$	9  I67 %)%8%8%C"VU%**,K!!61+. 	C'C!%,G5%FEMMO bzK'$i'%&"7+ Q2!9{*LLL="(KLL$-3AY-B'KQ KKM+	rK   c                 n    t        |       t        |      k7  rt        S | j                  |j                  k(  S rG   typeNotImplementedr7  r9   others     rD   __eq__zGlyph.__eq__I  +    :e$!!}}..rK   c                 >    | j                  |      }|t        u r|S | S rG   r  r  r9   r  results      rD   __ne__zGlyph.__ne__N  $    U#>1vA6zArK   )rK   )T)r   )r   r   )!r   r   r   r   r5  r   rI   rV   r}   r   r]  r\  r=  r>  r?  rv  rB  rC  rD  r  r  r   r  r   r   r   r  r  r   r
  r  r  r   r  rK   rD   r4   r4     s    ,
,.$ ,'R4ClJ(A*.6p*1X G,.=`>=@ 59 $ AE (T//I7V+ZdL'eN%N/
BrK   r4   r   r  r  r  returnc                     t        |       } t        |      }t        |      }| |z   dz  j                  |      xs& t        |       t        |      z   t        |      dz  k(  S )Nr  r!   )r   isclose_roundv)r  r  r  s      rD   _is_mid_pointr&  X  sW    	B	B	B"WO$$R(XGBK'"+,EQSWX,XXrK   interpolatable_glyphsc                  :   t        ddd      }dg }t        |       D ]G  \  }}|j                  dk  r|j                  D ]F  }t	        ||      }t	        ||      }|t        |||       +||k7  s1t        d| d| d| d|        t               }d}	|j                  |j                  |j                  }
|
D ]  }t        |	|dz         D ]g  }|   t        z  s||	kD  r|dz
  n|}||k  r|dz   n|	}|   t        z  s|   |   k7  r@t        |   |   |         sW|j                  |       i |dz   }	 |nj                  |       |j!                  |       J r |j                  J t#        j"                  d	fd
t        t%                    D              }|j                  }|J g }d}d}t'              D ]4  }|||   kD  r%|j!                  ||   |z
         |dz  }|||   kD  r%|dz  }6 |t%        |      k  r+|j!                  ||   |z
         |dz  }|t%        |      k  r+|D ]H  }|j                  t)        fdt        t%                    D              |_        ||_	        ||_
        J S t               S )a  Drop impliable on-curve points from the (simple) glyph or glyphs.

    In TrueType glyf outlines, on-curve points can be implied when they are located at
    the midpoint of the line connecting two consecutive off-curve points.

    If more than one glyphs are passed, these are assumed to be interpolatable masters
    of the same glyph impliable, and thus only the on-curve points that are impliable
    for all of them will actually be implied.
    Composite glyphs or empty glyphs are skipped, only simple glyphs with 1 or more
    contours are considered.
    The input glyph(s) is/are modified in-place.

    Args:
        interpolatable_glyphs: The glyph or glyphs to modify in-place.

    Returns:
        The set of point indices that were dropped if any.

    Raises:
        ValueError if simple glyphs are not in fact interpolatable because they have
        different point flags or number of contours.

    Reference:
    https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
    N)rv   r   rM  r   zIncompatible z for glyph at master index z: expected z, found r   r  c              3   2   K   | ]  }|vs|     y wrG   r  )r  r@   dropr   s     rD   r  z+dropImpliedOnCurvePoints.<locals>.<genexpr>  s     Gq$%(G   	
c              3   2   K   | ]  }|vs|     y wrG   r  )r  r@   r   r*  s     rD   r  z+dropImpliedOnCurvePoints.<locals>.<genexpr>  s       1$q	1r+  )r   rX   rv   r7  r   r   r   rU   r   r   rM  r0   r
  r&  rw   intersection_updaterW   rp  r1   sortedr   )r'  staticAttributessimple_glyphsr@   rC   r   expectedfoundmay_dropr  rM  rR  prvnxtnewFlagsr   	newEndPtsdeltar   r   r*  r   s                      @@@rD   dropImpliedOnCurvePointsr9  `  s$   4 'TD DM34 )$5!!A%$-- 		D/6HE4(E($6U" #D6)DQC H  (z%: 		 5"" &&+<<$ 	D5$(+  a;. 5ya!ed 4xa!eU#J,suSz1I$VC[&)VC[IQ  1HE	 <D$$X.U#S)$V  &&   ;;GE#e*$5G
 "22!!!	 	AfQi-  U!23Q fQi- QJE		
 #f+oVAY./FA #f+o # 	/E&&F 0 1#(V#51 !E #EK%.E"	/ #4..rK   c                   @    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)rX  a?  Represents a component within a composite glyph.

    The component is represented internally with four attributes: ``glyphName``,
    ``x``, ``y`` and ``transform``. If there is no "two-by-two" matrix (i.e
    no scaling, reflection, or rotation; only translation), the ``transform``
    attribute is not present.
    c                      y rG   r  r   s    rD   r5  zGlyphComponent.__init__  s    rK   c                     t        | d      r2| j                  \  \  }}\  }}||||| j                  | j                  f}ndddd| j                  | j                  f}| j                  |fS )a  Return information about the component

        This method returns a tuple of two values: the glyph name of the component's
        base glyph, and a transformation matrix. As opposed to accessing the attributes
        directly, ``getComponentInfo`` always returns a six-element tuple of the
        component's transformation matrix, even when the two-by-two ``.transform``
        matrix is not present.
        r   r   r   )rR   r   r   r   rA   )r9   xxxyyxyytranss         rD   r  zGlyphComponent.getComponentInfo  sg     4%#'>> Xb"xBRTVVTVV4E1a0E~~u$$rK   c                    t        j                  d|d d       \  }}t        |      | _        t        |      }|j	                  t        |            | _        |dd  }| j                  t        z  r}| j                  t        z  r't        j                  d|d d       \  | _        | _	        n=t        j                  d|d d       \  }}t        |      t        |      c| _
        | _        |dd  }n|| j                  t        z  r't        j                  d|d d       \  | _        | _	        n=t        j                  d|d d       \  }}t        |      t        |      c| _
        | _        |dd  }| j                  t        z  rBt        j                  d|d d       \  }t        |d      d	gd	t        |d      gg| _        |dd  }n| j                  t        z  rCt        j                  d|d d       \  }}	t        |d      d	gd	t        |	d      gg| _        |dd  }nk| j                  t         z  rXt        j                  d
|d d       \  }}
}}	t        |d      t        |
d      gt        |d      t        |	d      gg| _        |dd  }| j                  t"        z  }| j                  t$        z  }| j                  t&        t(        z  t*        z  t,        z  t.        z  t0        z  z  | _        |||fS )Nr  r'   >hh>bbr!   >BBr     r   >hhhhr  )r   rf  r+   r   r   rA   r  ARGS_ARE_XY_VALUESr   r   r  r  r  fi2flr   r  r  r  r  ROUND_XY_TO_GRIDUSE_MY_METRICSr  r  NON_OVERLAPPINGOVERLAP_COMPOUND)r9   r:   r9  r   r   r   r   scalexscaleyscalescale01scale10rh  rQ  s                 rD   rE   zGlyphComponent.decompile  s   ud2Ah7wZ
g,"//G=ABx::--zz..!'ud2Ah!?}}UD!H51.1!fc!f+dm8Dzz..!'ud2Ah!?}}UD!H51.1!fc!f+dm8D::'}}T484HUub!1%E%$%DN 8DZZ22#]]5$r(;NFFvr"A&E&"%&DN 8DZZ..17wRa1Q.VWgvvr"E'2$67w#U62%67DN 8DzzO+::(<<ZZ%& (( 	
 

 %t++rK   c                 j   d}| j                   t        t        z  t        z  t        z  t
        z  t        z  z  }|r	|t        z  }|r	|t        z  }t        | d      rd| j                  cxk  rdk  rJn nGd| j                  cxk  rdk  r2n n/|t        j                  d| j                  | j                        z   }n|t        j                  d| j                  | j                        z   }|t        z  }nt        | j                         }t        | j"                        }|t$        z  }d|cxk  rdk  r,n n)d|cxk  rdk  rn n|t        j                  d	||      z   }n#|t        j                  d
||      z   }|t        z  }t        | d      r| j&                  D cg c]  }|D cg c]  }t)        |d       c} }	}}|	d   d   s|	d   d   r>|t*        z  }|t        j                  d|	d   d   |	d   d   |	d   d   |	d   d         z   }ni|	d   d   |	d   d   k7  r0|t,        z  }|t        j                  d
|	d   d   |	d   d         z   }n(|t.        z  }|t        j                  d|	d   d         z   }|j1                  | j2                        }
t        j                  d||
      |z   S c c}w c c}}w )NrK   r  r   r	  rE  r  i   rD  rC  r   rF  r   rG  r  )r   rJ  rK  r  r  rL  rM  r  r  rR   r  r  r   r!  r  r   r   r   rH  r   fl2fir  r  r  r   rA   )r9   rh  rQ  r9  r:   r   r   r   rowr   r   s              rD   rV   zGlyphComponent.compile'  s    

%& (( 	
 
 O+E00E4#T\\(S(qDMM/HS/Hfkk%t}}MMfkk%t}}MM 55AA..E S tq'7C'7fkk%A66fkk%A66 554%@DO41%2,4OIO|A)A,q/ 44fkkaLOaLOaLOaLO  1aIaLO3 88fkk%1a)A,q/RR/fkk$	!Q@@&&t~~6{{5%1D88% 5Os   	J/#J*6J/*J/c           	         d| j                   fg}t        | d      s |d| j                  fd| j                  fgz   }n|d| j                  fd| j
                  fgz   }t        | d      r| j                  }|d   d   s|d   d   rR|d	t        |d   d   d
      fdt        |d   d   d
      fdt        |d   d   d
      fdt        |d   d   d
      fgz   }nU|d   d   |d   d   k7  r,|d	t        |d   d   d
      fdt        |d   d   d
      fgz   }n|dt        |d   d   d
      fgz   }|dt        | j                        fgz   }|j                  d|       |j                          y )NrA   r  r   r   r  r   r   r   scalexrF  rQ  rR  scaleyrN  r   r   )rA   rR   r   r   r  r  r   fl2strhexr   r{   ro   )r9   r   r;   r   r   s        rD   r}   zGlyphComponent.toXML]  s   t~~./tY'c466]S$&&M::Ei6T]]8STTE4%I|A)A,q/vil1or:;y|A ;<y|A ;<vil1or:;	!  1aIaLO3vil1or:;vil1or:;! 
 '6)A,q/2+F!G HH'3tzz?344e,rK   c                    |d   | _         d|v r't        |d         | _        t        |d         | _        n&t        |d         | _        t        |d         | _        d|v rJt        |d   d      }t        |d   d      }t        |d	   d      }t        |d
   d      }||g||gg| _        nPd|v r,t        |d   d      }t        |d
   d      }|dgd|gg| _        n d|v rt        |d   d      }	|	dgd|	gg| _        t        |d         | _        y )NrA   r  r  r   r   rQ  rX  rF  rR  rY  r   rN  r   )	rA   r	   r  r  r   r   str2flr   r   )
r9   ri   r   r   r;   rX  rQ  rR  rY  rN  s
             rD   r   zGlyphComponent.fromXMLx  s0   {+#E)$45DL$U:%67DMeCj)DFeCj)DFE(OR0FU9-r2GU9-r2GE(OR0F%w/'61BCDNE(OR0FE(OR0F%qkAv;7DN5>2.E$aj1e*5DNeGn-
rK   c                 n    t        |       t        |      k7  rt        S | j                  |j                  k(  S rG   r  r  s     rD   r  zGlyphComponent.__eq__  r  rK   c                 >    | j                  |      }|t        u r|S | S rG   r  r  s      rD   r   zGlyphComponent.__ne__  r!  rK   N)r   r   r   r   r5  r  rE   rV   r}   r   r  r   r  rK   rD   rX  rX    s2    %*5,n49l6../
BrK   rX  c                   H    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dZdZdZdZy)VarComponentFlagsr   r!   r'   r  r  r  r  r  r)  r*  r+  r,  r-  i    i @  N)r   r   r   rK  AXIS_INDICES_ARE_SHORTUNIFORM_SCALEHAVE_TRANSLATE_XHAVE_TRANSLATE_YHAVE_ROTATIONHAVE_SCALE_XHAVE_SCALE_YHAVE_SKEW_XHAVE_SKEW_YHAVE_TCENTER_XHAVE_TCENTER_YGID_IS_24BITAXES_HAVE_VARIATIONRESET_UNSPECIFIED_AXESr  rK   rD   ra  ra    sR    N#MMLLKKNNL #rK   ra  "VarComponentTransformMappingValues)r  fractionalBitsrN  defaultValue      r  L)	
translateX
translateYrotationscaleXscaleYskewXskewYtCenterXtCenterYc                   \    e Zd ZdZd Zed        Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zy)rY     c                 0    i | _         t               | _        y rG   )locationr   r   r   s    rD   r5  zGlyphVarComponent.__init__  s    ,.rK   c                 n   d}t        j                  d| d d       d   }t        | d         }|t        j                  z  r|dz  }||z  }|t        j
                  z  r	|d|z  z  }nt        j                  d| d |       }||z  }t        j                         D ]  \  }}||j                  z  s|dz  } |S )Nr  >Hr!   r   r   r  )
r   rf  r+   ra  rm  rb  rp  VAR_COMPONENT_TRANSFORM_MAPPINGitemsr  )r:   rO   r   numAxesaxisIndices	attr_namemapping_valuess          rD   r  zGlyphVarComponent.getSize  s    dD!H-a0d1g,$111AID$;;;AKD++c4>:KGOD)H)N)N)P 	%I~~***		 rK   c           	         t        j                  d|d d       d   t              | _        |dd  }t        |d         }|dd  }t        j
                  z  rAt        t        j                  dd|d d z         d         }|dd  }t        j
                  z  n*t        t        j                  d|d d       d         }|dd  }|j                  t        |            | _        t        j                  z  r[t        j                  d|d d|z         }t        j                  d	k7  r|j                          |d|z  d  }t        j                  z  nt        j                  d
|d |       }||d  }t        |      |k(  sJ t        |      }t        j                  d|d d|z         }t        j                  d	k7  r|j                          |d|z  d  }t        |      |k(  sJ |D cg c]  }t        |d       }}t!        ||      D ci c]  \  }}|j"                  |   | c}}| _        fd}	t&        j)                         D ](  \  }
} |	||      \  }}t+        | j,                  |
|       * t        j.                  z  rqt        j0                  z  rKt        j2                  z  s8| j,                  j4                  | j,                  _        t        j2                  z  t        j.                  z  |S c c}w c c}}w )Nr  r!   r   r   >LrP   r  rn  ro  r  r  rF  c           	          |j                   z  rB| dd  t        t        j                  d| d d       d   |j                        |j
                  z  fS | |j                  fS )Nr!   r  r   )r  rI  r   rf  rq  rN  rr  )r:   rH   r   s     rD   read_transform_componentz=GlyphVarComponent.decompile.<locals>.read_transform_component  sg    v{{"H&--d2Ah7:F<Q<QRll#  V0000rK   )r   rf  r+   r   ra  rm  r   rA   rb  rp  rr  rs  rt  r1   r   rI  r   r*   r  r  r  r   r   rc  rg  rh  ry  rz  )r9   r:   r9  r  r   r  
axisValuesr  r@   r  r  r  valuer   s                @rD   rE   zGlyphVarComponent.decompile  s   dD!H-a0Z
ABxd1g,ABx$111&--ed2Ah.>?BCG8D&333E&--d2Ah7:;G8D"//G=$;;;++c4!g++>?K}}%$$&G&D&===E++c4>:K>D;7***;'[[d=Q[&9:
==E!!AKM":'))),67qeArl7
7 25[*1M
)-AIq!1$
	1 *I)N)N)P 	6%I~24HKD%DNNIu5	6 $222(555)666(,(=(=%*777&444E9 8
s   %K6	K;c                    d}t        | d      sdt        j                         D ]|  \  }}t        | j                  |      }t        ||j                  z  |j                        t        |j                  |j                  z  |j                        k7  sn|j                  z  ~ n| j                  t        j                  z  rzt        j                  z  rgt        | j                  j                  d      t        | j                  j                  d      k(  r&t        j                   z  t        j                  z  t#        | j$                        }|t'        j(                  d|      z   }|j+                  | j,                        }|dkD  r0t        j.                  z  |t'        j(                  d|      dd  z   }n|t'        j(                  d	|      z   }| j$                  j1                         D cg c]  }|j2                  j5                  |       }	}t7        d
 |	D              rt9        j8                  d|	      }	nLt9        j8                  d|	      }	t:        j<                  dk7  r|	j?                          t        j@                  z  |tC        |	      z   }| j$                  jE                         }
t9        j8                  dd |
D              }
t:        j<                  dk7  r|
j?                          |tC        |
      z   }fd}t        j                         D ]%  \  }}t        | j                  |      } ||||      }' t'        j(                  d	      |z   S c c}w )NrK   r   r   r  z>Bi  r  r   r  c              3   &   K   | ]	  }|d k    yw)r	  Nr  )r  as     rD   r  z,GlyphVarComponent.compile.<locals>.<genexpr>U  s     -AqCx-s   r  rn  ro  r  c              3   4   K   | ]  }t        |d         yw)rF  N)rU  )r  r  s     rD   r  z,GlyphVarComponent.compile.<locals>.<genexpr>_  s     &HuQ|&Hs   c                     |j                   z  r:| t        j                  dt        ||j                  z  |j
                              z   S | S )Nr  )r  r   r!  rU  rN  rq  )r:   r  rH   r   s      rD   write_transform_componentz<GlyphVarComponent.compile.<locals>.write_transform_componentd  sI    v{{"fkk% 4f6K6KL   rK   )#rR   r  r  r   r   rU  rN  rq  rr  r  r   ra  rg  rh  ry  rz  rc  r1   r  r   r!  r   rA   rm  r   r*   r  r  rp  rr  rs  rt  rb  bytesrH   )r9   r9  r:   r  mappingr  r  r   tagr  r  r  r  r   s                @rD   rV   zGlyphVarComponent.compile2  s   tW%E&E&K&K&M *"	7	:.0F0FG5((7==8':P:PL  W\\)E* JJE %222)666dnn++R0E$..:O:OQS4TT&444E&333Edmm$fkk$00&&t~~6U?&333E&++dG4QR88D&++dG44D@D@R@R@TUy))//4UU---++c;7K++c;7K}}%$$&&===EeK((]]))+
[[&HZ&HI
==E!!eJ''	 *I)N)N)P 	J%I~DNNI6E,T5.ID	J {{4'$..9 Vs   2"Mc           
         d| j                   fg}t        | d      r|dt        | j                        fgz   }t        j                         D ]R  \  }}t        | j                  |      }||j                  k7  s,|j                  |t        ||j                        f       T |j                  d|       |j                          |j                  d       |j                          | j                  j                         D ]7  \  }}|j                  dd|fdt        |d      fg       |j                          9 |j!                  d       |j                          |j!                  d       |j                          y )	NrA   r   rU  r  r<   r  r  rF  )rA   rR   r[  r   r  r  r   r   rr  rW   rZ  rq  rz   ro   r  r{   r~   )r9   r   r;   r   r  r  r  r  s           rD   r}   zGlyphVarComponent.toXMLr  s>   t~~./4!gs4::788E"A"G"G"I 	MIw	2AG(((i73I3I)JKL	M
 	.
#mm))+ 	FCVuclWfQm4L%MNNN	 	j!n%rK   c                    |d   | _         d|v rt        |d         | _        t        j	                         D ]C  \  }}||vrt        t        ||         |j                        }t        | j                  ||       E |D ]p  }t        |t              s|\  }}}|dk7  r |D ]L  }t        |t              s|\  }}}|dk(  sJ |rJ t        t        |d         d      | j                  |d   <   N r y )NrA   r   r  r<   r  rF  r  )rA   r	   r   r  r  r]  rq  r   r   r   r   r  )	r9   ri   r   r   r;   r  r  r  r   s	            rD   r   zGlyphVarComponent.fromXML  s   {+e!%.1DJ"A"G"G"I 	2Iw%xi 0173I3IJADNNIq1		2  	SAa'#$ D%z! S!!U+'($eWv~%~""{.4XeGn5Mr.ReEl+S	SrK   c                 v   t        | d      sJ d       d}| j                  t        j                  z  r|t	        | j
                        z  }| j                  t        j                  t        j                  z  z  r|dz  }| j                  t        j                  z  r|dz  }| j                  t        j                  t        j                  z  z  r|dz  }| j                  t        j                  t        j                  z  z  r|dz  }| j                  t        j                  t        j                  z  z  r|dz  }|S )Nr   z,VarComponent with variations must have flagsr   r   )rR   r   ra  rn  r1   r  rd  re  rf  rg  rh  ri  rj  rk  rl  )r9   r  s     rD   getPointCountzGlyphVarComponent.getPointCount  s   tW%U'UU%::)===S''E::..1B1S1SS
 QJE::)777QJE::**->-K-KK
 QJE::*669J9V9VVWQJE::,,/@/O/OO
 QJErK   c                    g }g }| j                   t        j                  z  rP| j                  j	                         D ]3  \  }}|j                  |       |j                  t        |d      df       5 | j                   t        j                  t        j                  z  z  rL|j                  d       |j                  | j                  j                  | j                  j                  f       | j                   t        j                  z  rE|j                  d       |j                  t        | j                  j                  dz  d      df       | j                   t        j                  t        j                  z  z  r`|j                  d       |j                  t        | j                  j                   d      t        | j                  j"                  d      f       | j                   t        j$                  t        j&                  z  z  rf|j                  d	       |j                  t        | j                  j(                  d
z  d      t        | j                  j*                  dz  d      f       | j                   t        j,                  t        j.                  z  z  rL|j                  d       |j                  | j                  j0                  | j                  j2                  f       ||fS )NrF  r   r  rx  rt  rs  rN  r  skewru  tCenter)r   ra  rn  r  r  rW   rU  rd  re  r   rv  rw  rf  rx  rg  rh  ry  rz  ri  rj  r{  r|  rk  rl  r}  r~  )r9   r   r   r  r  s        rD   r   z+GlyphVarComponent.getCoordinatesAndControls  s5   ::)===----/ 1Q$uQ|Q/01 ::..1B1S1SS
 OOK(MM4>>44dnn6O6OPQ::)777OOJ'MM5!8!83!>CQGH::**->-K-KK
 OOG$MMt~~,,b159N9NPR3ST ::*669J9V9VVWOOF#MM$....5r:$....4b9 ::,,/@/O/OO
 OOI&MM4>>22DNN4K4KLMxrK   c                    d}| j                   t        j                  z  r4i }| j                  D ]  }t	        ||   d   d      ||<   |dz  } || _        t               | _        | j                   t        j                  t        j                  z  z  r+||   \  | j                  _	        | j                  _
        |dz  }| j                   t        j                  z  r)t	        ||   d   d      dz  | j                  _        |dz  }| j                   t        j                  t        j                  z  z  rHt	        ||   d   d      t	        ||   d   d      c| j                  _        | j                  _        |dz  }| j                   t        j"                  t        j$                  z  z  rNt	        ||   d   d      dz  t	        ||   d   d      dz  c| j                  _        | j                  _        |dz  }| j                   t        j*                  t        j,                  z  z  r+||   \  | j                  _        | j                  _        |dz  }||d  S )Nr   rF  r   rs  rt  r  ru  )r   ra  rn  r  rI  r   r   rd  re  rv  rw  rf  rx  rg  rh  ry  rz  ri  rj  r{  r|  rk  rl  r}  r~  )r9   r   r@   newLocationr  s        rD   r   z GlyphVarComponent.setCoordinates  s   ::)===K}} #(1r#:C Q (DM,.::..1B1S1SS
 DJ!9@DNN%t~~'@FA::)777&+F1IaL"&=&CDNN#FA::**->-K-KK
 <Aq	!b<VAYq\2& 9DNN!4>>#8 FA::*669J9V9VVWfQilB'$.fQilB'#- 7DNN $.."6 FA::,,/@/O/OO
 @Fay<DNN#T^^%<FAabzrK   c                 n    t        |       t        |      k7  rt        S | j                  |j                  k(  S rG   r  r  s     rD   r  zGlyphVarComponent.__eq__	  r  rK   c                 >    | j                  |      }|t        u r|S | S rG   r  r  s      rD   r   zGlyphVarComponent.__ne__	  r!  rK   N)r   r   r   rl  r5  staticmethodr  rE   rV   r}   r   r  r   r   r  r   r  rK   rD   rY  rY    sS    H/  *>@>/@2S46& P&P/
BrK   rY  c                      e Zd ZdZg fdZed        Zed        Zd Z	d Z
d Zd Zd	 Zd
 Zd Zd ZeddZd ZefdZd Zd Zd Zd Zd Zd Zd Zd Zd ZeddZd Zd Z d Z!d Z"eZ#e!Z$d Z%d  Z&d! Z'd" Z(d# Z)d$ Z*e*Z+y%)&r   zA list of glyph coordinates.

    Unlike an ordinary list, this is a numpy-like matrix object which supports
    matrix addition, scalar multiplication and other operations described below.
    c                 Z    t        j                   d      | _        | j                  |       y )Nr   )rp  _ar   )r9   iterables     rD   r5  zGlyphCoordinates.__init__!	  s    ++c"HrK   c                     | j                   S )z+Returns the underlying array of coordinates)r  r   s    rD   rp  zGlyphCoordinates.array%	  s     wwrK   c                     t               }|j                  j                  t        | dz  |j                  j                  z               |S )zKCreates a new ``GlyphCoordinates`` object with all coordinates set to (0,0)r!   )r   r  rq  r  itemsize)r  r  s     rD   rw  zGlyphCoordinates.zeros*	  s7     	uUQY678rK   c                 d    t               }|j                  j                  | j                         |S )zMCreates a new ``GlyphCoordinates`` object which is a copy of the current one.)r   r  r   )r9   r   s     rD   r   zGlyphCoordinates.copy1	  s#    	DGGrK   c                 2    t        | j                        dz  S )z/Returns the number of coordinates in the array.r!   r1   r  r   s    rD   r   zGlyphCoordinates.__len__7	  s    477|q  rK   c                    | j                   }t        |t              rt        |j	                  t        |              }g }|D ]^  }|d|z     }|d|z  dz      }|j                  |j                         rt        |      n||j                         rt        |      n|f       ` |S |d|z     }|d|z  dz      }|j                         rt        |      n||j                         rt        |      fS |fS )z!Returns a two element tuple (x,y)r!   r   )	r  r   slicer0   r_   r1   rW   r  r+   )r9   r  r  r_   retr   r   s          rD   r   zGlyphCoordinates.__getitem__;	  s    GGaQYYs4y12GC a!eHa!eaiL

 ||~SV1c!fTUV Ja!eHa!eaiL,,.Aa1<<>QQQqQQrK   c                     t        |t              r<t        |j                  t	        |              }t        |      D ]  \  }}||   | |<    y|\  | j                  d|z  <   | j                  d|z  dz   <   y)z7Sets a point's coordinates to a two element tuple (x,y)Nr!   r   )r   r  r0   r_   r1   rX   r  )r9   r  r  r_   rS  r@   s         rD   r   zGlyphCoordinates.__setitem__M	  sr    aQYYs4y12G!'* 1A$Q-.*AA	*rK   c                 n    d|z  t        | j                        z  }| j                  |= | j                  |= y)zRemoves a point from the listr!   Nr  )r9   r@   s     rD   r   zGlyphCoordinates.__delitem__W	  s.    Uc$''l"GGAJGGAJrK   c                 >    ddj                  d | D              z   dz   S )NzGlyphCoordinates([,c              3   2   K   | ]  }t        |        y wrG   )str)r  r   s     rD   r  z,GlyphCoordinates.__repr__.<locals>.<genexpr>^	  s     .D!s1v.Ds   z]))rY   r   s    rD   __repr__zGlyphCoordinates.__repr__]	  s!    #chh.Dt.D&DDtKKrK   c                 L    | j                   j                  t        |             y rG   )r  r   r   )r9   r   s     rD   rW   zGlyphCoordinates.append`	  s    uQx rK   c                 H    |D ]  }| j                   j                  |        y rG   )r  r   )r9   r  r   s      rD   r   zGlyphCoordinates.extendc	  s!     	AGGNN1	rK   r   c                |    |t         u ry | j                  }t        t        |            D ]  } |||         ||<    y rG   )r   r  r0   r1   )r9   r   r  r@   s       rD   r   zGlyphCoordinates.toIntg	  s>    GGGs1v 	A1;AaD	rK   c                     | j                   }|sy|dd d   }|dd d   }t        |      t        |      t        |      t        |      fS )Nr  r   r!   r   )r  r  r^  )r9   r  xsyss       rD   
calcBoundszGlyphCoordinates.calcBoundsn	  sN    GGqt!tWqt!tW2wBR#b'11rK   c                 H    t        fd| j                         D              S )Nc              3   .   K   | ]  } |        y wrG   r  )r  r  r   s     rD   r  z1GlyphCoordinates.calcIntBounds.<locals>.<genexpr>w	  s     9!U1X9s   )r   r  )r9   r   s    `rD   r  zGlyphCoordinates.calcIntBoundsv	  s    9t'8999rK   c                     | j                   }d\  }}t        dt        |      d      D ]"  }||   |z   x||<   }||dz      |z   x||dz   <   }$ y N)r   r   r   r!   r   r  r0   r1   )r9   r  r   r   r@   s        rD   rx  z#GlyphCoordinates.relativeToAbsolutey	  sd    GG1q#a&!$ 	(AtaxAaD1QU8a<'Aa!eHq	(rK   c                     | j                   }d\  }}t        dt        |      d      D ]&  }||   }||dz      }||z
  ||<   ||z
  ||dz   <   |}|}( y r  r  )r9   r  r   r   r@   nxnys          rD   r  z#GlyphCoordinates.absoluteToRelative	  sn    GG1q#a&!$ 	A1B1q5B6AaDAvAa!eHAA	rK   c                     |\  }}|dk(  r|dk(  ry| j                   }t        dt        |      d      D ]  }||xx   |z  cc<   ||dz   xx   |z  cc<   ! y)zA
        >>> GlyphCoordinates([(1,2)]).translate((.5,0))
        r   Nr!   r   r  r9   r   r   r   r  r@   s         rD   r  zGlyphCoordinates.translate	  `     16a1fGGq#a&!$ 	AaDAIDa!eHMH	rK   c                     |\  }}|dk(  r|dk(  ry| j                   }t        dt        |      d      D ]  }||xx   |z  cc<   ||dz   xx   |z  cc<   ! y)z=
        >>> GlyphCoordinates([(1,2)]).scale((.5,0))
        r   Nr   r!   r  r  s         rD   rN  zGlyphCoordinates.scale	  r  rK   c                     | j                   }t        dt        |      d      D ]J  }||   }||dz      }||d   d   z  ||d   d   z  z   }||d   d   z  ||d   d   z  z   }|||<   |||dz   <   L y)zK
        >>> GlyphCoordinates([(1,2)]).transform(((.5,0),(.2,.5)))
        r   r!   r   Nr  )r9   r  r  r@   r   r   pxpys           rD   r   zGlyphCoordinates.transform	  s     GGq#a&!$ 	A!A!a%AQqT!Wq1Q47{*BQqT!Wq1Q47{*BAaDAa!eH	rK   c                 n    t        |       t        |      k7  rt        S | j                  |j                  k(  S )z
        >>> g = GlyphCoordinates([(1,2)])
        >>> g2 = GlyphCoordinates([(1.0,2)])
        >>> g3 = GlyphCoordinates([(1.5,2)])
        >>> g == g2
        True
        >>> g == g3
        False
        >>> g2 == g3
        False
        )r  r  r  r  s     rD   r  zGlyphCoordinates.__eq__	  s-     :e$!!ww%((""rK   c                 >    | j                  |      }|t        u r|S | S )z
        >>> g = GlyphCoordinates([(1,2)])
        >>> g2 = GlyphCoordinates([(1.0,2)])
        >>> g3 = GlyphCoordinates([(1.5,2)])
        >>> g != g2
        False
        >>> g != g3
        True
        >>> g2 != g3
        True
        r  r  s      rD   r   zGlyphCoordinates.__ne__	  s&     U#>1vA6zArK   c                 "    | j                         S )a-  
        >>> g = GlyphCoordinates([(1,2)])
        >>> g
        GlyphCoordinates([(1, 2)])
        >>> g2 = +g
        >>> g2
        GlyphCoordinates([(1, 2)])
        >>> g2.translate((1,0))
        >>> g2
        GlyphCoordinates([(2, 2)])
        >>> g
        GlyphCoordinates([(1, 2)])
        )r   r   s    rD   __pos__zGlyphCoordinates.__pos__	  s     yy{rK   c                     | j                         }|j                  }t        t        |            D ]  }||    ||<    |S )z
        >>> g = GlyphCoordinates([(1,2)])
        >>> g
        GlyphCoordinates([(1, 2)])
        >>> g2 = -g
        >>> g2
        GlyphCoordinates([(-1, -2)])
        >>> g
        GlyphCoordinates([(1, 2)])
        )r   r  r0   r1   )r9   rr  r@   s       rD   __neg__zGlyphCoordinates.__neg__	  sC     IIKDDs1v 	AaD5AaD	rK   c                J    | j                         }|j                  |       |S )Nr   )r   r   )r9   r   r  s      rD   	__round__zGlyphCoordinates.__round__	  s     IIK	erK   c                 @    | j                         j                  |      S rG   )r   __iadd__r  s     rD   __add__zGlyphCoordinates.__add__	      yy{##E**rK   c                 @    | j                         j                  |      S rG   )r   __isub__r  s     rD   __sub__zGlyphCoordinates.__sub__	  r  rK   c                 @    | j                         j                  |      S rG   )r   __imul__r  s     rD   __mul__zGlyphCoordinates.__mul__	  r  rK   c                 @    | j                         j                  |      S rG   )r   __itruediv__r  s     rD   __truediv__zGlyphCoordinates.__truediv__ 
  s    yy{''..rK   c                     ||  z   S rG   r  r  s     rD   __rsub__zGlyphCoordinates.__rsub__
  s    rK   c                 L   t        |t              r#t        |      dk(  sJ | j                  |       | S t        |t              r\|j
                  }| j
                  }t        |      t        |      k(  sJ t        t        |            D ]  }||xx   ||   z  cc<    | S t        S )z
        >>> g = GlyphCoordinates([(1,2)])
        >>> g += (.5,0)
        >>> g
        GlyphCoordinates([(1.5, 2)])
        >>> g2 = GlyphCoordinates([(3,4)])
        >>> g += g2
        >>> g
        GlyphCoordinates([(4.5, 6)])
        r!   r   r   r1   r  r   r  r0   r  r9   r  r  r@   s       rD   r  zGlyphCoordinates.__iadd__	
  s     eU#u:?"?NN5!Ke-.HHEAq6SZ'''3q6] !!a !KrK   c                 `   t        |t              r-t        |      dk(  sJ | j                  |d    |d    f       | S t        |t              r\|j
                  }| j
                  }t        |      t        |      k(  sJ t        t        |            D ]  }||xx   ||   z  cc<    | S t        S )z
        >>> g = GlyphCoordinates([(1,2)])
        >>> g -= (.5,0)
        >>> g
        GlyphCoordinates([(0.5, 2)])
        >>> g2 = GlyphCoordinates([(3,4)])
        >>> g -= g2
        >>> g
        GlyphCoordinates([(-2.5, -2)])
        r!   r   r   r  r  s       rD   r  zGlyphCoordinates.__isub__!
  s     eU#u:?"?NNU1XIay12Ke-.HHEAq6SZ'''3q6] !!a !KrK   c                 
   t        |t              r#t        |      dk(  sJ | j                  |       | S t        |t              r;|dk(  r| S | j
                  }t        t        |            D ]  }||xx   |z  cc<    | S t        S )z
        >>> g = GlyphCoordinates([(1,2)])
        >>> g *= (2,.5)
        >>> g *= 2
        >>> g
        GlyphCoordinates([(4, 2)])
        >>> g = GlyphCoordinates([(1,2)])
        >>> g *= 2
        >>> g
        GlyphCoordinates([(2, 4)])
        r!   r   )r   r   r1   rN  r   r  r0   r  r  s       rD   r  zGlyphCoordinates.__imul__9
  s}     eU#u:?"?JJuKeV$zA3q6] !KrK   c                     t        |t              r||f}t        |t              r8|dk(  r| S t        |      dk(  sJ | j	                  d|d   z  d|d   z  f       | S t
        S )z
        >>> g = GlyphCoordinates([(1,3)])
        >>> g /= (.5,1.5)
        >>> g /= 2
        >>> g
        GlyphCoordinates([(1, 1)])
        )r   r   r!   g      ?r   r   )r   r   r   r1   rN  r  r  s     rD   r  zGlyphCoordinates.__itruediv__R
  si     eV$ENEeU#u:?"?JJeAheAh78KrK   c                 ,    t        | j                        S )aH  
        >>> g = GlyphCoordinates([])
        >>> bool(g)
        False
        >>> g = GlyphCoordinates([(0,0), (0.,0)])
        >>> bool(g)
        True
        >>> g = GlyphCoordinates([(0,0), (1,0)])
        >>> bool(g)
        True
        >>> g = GlyphCoordinates([(0,.5), (0,0)])
        >>> bool(g)
        True
        )rW  r  r   s    rD   __bool__zGlyphCoordinates.__bool__d
  s     DGG}rK   N),r   r   r   r   r5  propertyrp  r  rw  r   r   r   r   r   r  rW   r   r   r   r  r  rx  r  r  rN  r   r  r   r  r  r  r  r  r  r  __radd____rmul__r  r  r  r  r  r  __nonzero__r  rK   rD   r   r   	  s     !#     !R$/L! % 2 #* :(	

# B" " ") 
+++/ HH002$" KrK   r   __main__){r   collectionsr   fontTools.miscr   	fontToolsr   r   fontTools.misc.transformr   fontTools.misc.textToolsr   r	   r
   fontTools.misc.arrayToolsr   r   fontTools.misc.bezierToolsr   fontTools.misc.fixedToolsr   rI  r   rU  r   rZ  r   r]  fontTools.misc.roundToolsr   r   fontTools.misc.vectorr   numbersr    r   r   rr  r   rp  loggingmathrq   r   fontTools.misc.filenamesr   fontTools.misc.loggingToolsr   enumr   	functoolsr   typesr   typingr   	getLoggerr   r5   rY   splitr  r#   r   r<  r
  r  r  r  r  r  rN  rO  ry  r  r  r  r  r$  r(  r  rH  rJ  r  rL  r  r  r  r  rK  rM  r  r  r.  objectr4   r  r%  r   rW  r&  r+   r9  rX  ra  rp  rd  re  rf  rg  rh  ri  rj  rk  rl  r  rY  r   doctestexittestmodfailedr  rK   rD   <module>r     s   < " "   8 9 9 ? :  7 (    
     	 $ 7 9   ! g!
 ((=7==%bq)
* "# @<\.. @<F @
  


		 	 ++i7	 qqBqB:A4=
    !      "  !H 
aBF aBL &""'
2Ye Y YE Yd Yh/U h/s3x h/VKBV KBh$ $$ &0(7& " 5**Aq! 5**Aq! 3''S! 1&&Aq 1&&Aq 0%%r4 0%%r3 3((!Q 3((!Q3# >BB BBJ
[v [|
 zCHH_W__%%& rK   