
    <`>a                        d Z ddlmZ d Zd Zd dZd Zd Zd	 Z G d
 de	          Z
d Zd!dZd dZd Zd Zd Zd Zd Z	 	 	 	 d"dZd dZedk    rddlZ eej                  dk    r&ddlZ ej         ej                    j                    eej        dd                   Z ed            e ee                      ee          Z ed            ee            ee          Z  ed            e ee                      ee k    sJ  ed            e e ee                                ed            e e ee                               dS dS )#aZ  T2CharString operator specializer and generalizer.

PostScript glyph drawing operations can be expressed in multiple different
ways. For example, as well as the ``lineto`` operator, there is also a
``hlineto`` operator which draws a horizontal line, removing the need to
specify a ``dx`` coordinate, and a ``vlineto`` operator which draws a
vertical line, removing the need to specify a ``dy`` coordinate. As well
as decompiling :class:`fontTools.misc.psCharStrings.T2CharString` objects
into lists of operations, this module allows for conversion between general
and specific forms of the operation.

    )maxStackLimitc                    t          | t                    r|                                 } g }| D ]Y}	 t          |          }n1# t          $ r$ 	 t          |          }n# t          $ r Y nw xY wY nw xY w|                    |           Z|S N)
isinstancestrsplitint
ValueErrorfloatappend)stringprogramtokens      <lib/python3.11/site-packages/fontTools/cffLib/specializer.pystringToProgramr      s    vs <<>>&  U	u::55	 	 	 		%LLEE
 	 	 	D		
 
..s5   A
A/AA/
A)&A/(A))A/.A/c                 @    d                     d | D                       S )N c              3   4   K   | ]}t          |          V  d S r   )r   ).0xs     r   	<genexpr>z"programToString.<locals>.<genexpr>$   s(      ))AQ))))))    )join)r   s    r   programToStringr   #   s#    ))))))))r   Nc                    d}d}d}d}g }g }t          |           }|D ]}	t          |	t                    s|                    |	           .|	dk    r\|J d ||          z   }
|d         }||
z  dz   }|| d         g|| d<   ||t	          |          z   dz
  z  }t	          |          }|	dk    r!|d         }t          |          t          u sJ no|sm|	dv rid	}|	d
v }|r|t	          ||d                   z   }nt	          |          }|r5|dz  |z  r-|                    d          }|                    d|gf           |	dv rV|r|                    d|f           |                    |	g f           |                    dt          |          gf           n|                    |	|f           g }|r|                    d|f           |S )u  Takes a T2CharString program list and returns list of commands.
	Each command is a two-tuple of commandname,arg-list.  The commandname might
	be empty string if no commandname shall be emitted (used for glyph width,
	hintmask/cntrmask argument, as well as stray arguments at the end of the
	program (¯\_(ツ)_/¯).
	'getNumRegions' may be None, or a callable object. It must return the
	number of regions. 'getNumRegions' takes a single argument, vsindex. If
	the vsindex argument is None, getNumRegions returns the default number
	of regions for the charstring, else it returns the numRegions for
	the vsindex.
	The Charstring may or may not start with a width value. If the first
	non-blend operator has an odd number of arguments, then the first argument is
	a width, and is popped off. This is complicated with blend operators, as
	there may be more than one before the first hint or moveto operator, and each
	one reduces several arguments to just one list argument. We have to sum the
	number of arguments that are not part of the blend arguments, and all the
	'numBlends' values. We could instead have said that by definition, if there
	is a blend operator, there is no width value, since CFF2 Charstrings don't
	have width values. I discussed this with Behdad, and we are allowing for an
	initial width value in this case because developers may assemble a CFF2
	charstring from CFF Charstrings, which could have width values.
	FNr   blend   vsindex>
   hstemvstemendcharhmovetohstemhmrmovetovmovetovstemhmcntrmaskhintmaskT>   r#   r&       >   r(   r)   )	iterr   r   r   lentyper	   popnext)r   getNumRegionsseenWidthOpvsIndexlenBlendStacklastBlendIndexcommandsstackitr   numSourceFonts	numBlendsnumBlendArgsparitynumArgswidths                   r   programToCommandsr?   '   sZ   0 	
7mm / /U	E3		 <<
g

#
#
#g...> Ry9n,q0<!<-..125,IE

*Q..=JJ>	2Y7
w--3




 #U '   ;++6  c%"8999GG%jjG #7Q;&( #IIaLLEOOR%M"""
&&& !OORK   ??E2;??Bb
#$$$$??E5>"""
%%	 
//2u+r   c                     g }| D ]W}t          |t                    r+|                    |           |                    d           B|                    |           X|S )Nr   )r   listextendr   )args
token_listargs      r   _flattenBlendArgsrF   |   sp      ST SWSr   c                     g }| D ]Y\  }}t          d |D                       rt          |          }|                    |           |r|                    |           Z|S )znTakes a commands list as returned by programToCommands() and converts
	it back to a T2CharString program list.c              3   @   K   | ]}t          |t                    V  d S r   r   rA   r   rE   s     r   r   z$commandsToProgram.<locals>.<genexpr>   ,      //3C		//////r   )anyrF   rB   r   )r6   r   oprC   s       r   commandsToProgramrN      sz       WR//$///// "
D
!
!4	.. 
>>"r   c              #      K   t          |           |z  dk    rt          |           t          dt          |           |          D ]}| |||z            V  dS )z'Group the list el into groups of size nr   N)r-   r
   range)elnis      r   _everyNrT      sh      GGaK1JrNN*
3r77A

  Q
1QqS5	//// r   c                   ,   e Zd Zed             Zed             Zed             Zed             Zed             Zed             Z	ed             Z
ed             Zed	             Zed
             Zed             Zed             Zed             ZdS )!_GeneralizerDecombinerCommandsMapc              #   Z   K   t          |           dk    rt          |           d| fV  d S )Nr*   r%   r-   r
   rC   s    r   r%   z)_GeneralizerDecombinerCommandsMap.rmoveto   s9      YY!^^:d+++	Dr   c              #   j   K   t          |           dk    rt          |           d| d         dgfV  d S Nr   r%   r   rX   rY   s    r   r#   z)_GeneralizerDecombinerCommandsMap.hmoveto   sA      YY!^^:d+++	T!WaL!!!!!!r   c              #   j   K   t          |           dk    rt          |           dd| d         gfV  d S r[   rX   rY   s    r   r&   z)_GeneralizerDecombinerCommandsMap.vmoveto   sA      YY!^^:d+++	QQL!!!!!!r   c              #   ^   K   | st          |           t          | d          D ]} d| fV  	d S )Nr*   rlinetor
   rT   rY   s    r   r^   z)_GeneralizerDecombinerCommandsMap.rlineto   sP      	%Z%%%dA  d
T	 r   c              #      K   | st          |           t          |           }	 	 dt          |          dgfV  ddt          |          gfV  +# t          $ r Y d S w xY wNTr^   r   r
   r,   r0   StopIterationrC   r8   s     r   hlinetoz)_GeneralizerDecombinerCommandsMap.hlineto   s      	%Z%%%Dzz"%tBxxm
$$$$q$r((m
$$$$% 
   44   ,A 
AAc              #      K   | st          |           t          |           }	 	 ddt          |          gfV  dt          |          dgfV  +# t          $ r Y d S w xY wra   rb   rd   s     r   vlinetoz)_GeneralizerDecombinerCommandsMap.vlineto   s      	%Z%%%Dzz"%q$r((m
$$$$tBxxm
$$$$% 
   44rf   c              #   ^   K   | st          |           t          | d          D ]} d| fV  	d S )N   	rrcurvetor_   rY   s    r   rk   z+_GeneralizerDecombinerCommandsMap.rrcurveto   sP      	%Z%%%dA  d
t	 r   c              #   |  K   t          |           dk     st          |           dz  dk    rt          |           t          |           dz  dk    r4d| d         | d         | d         | d         | d         dgfV  | dd          } t          | d          D ]&} d| d         d| d         | d         | d         dgfV  'd S N   r   r*   rk   r         r-   r
   rT   rY   s    r   	hhcurvetoz+_GeneralizerDecombinerCommandsMap.hhcurveto   s      YY]]c$ii!ma''z$/?/?)?YY]a
Qa$q'47DGQG	HHHH
qrr(4dA C Cd
QDGT!Wd1gqA	BBBBBC Cr   c           	   #   |  K   t          |           dk     st          |           dz  dk    rt          |           t          |           dz  dk    r4d| d         | d         | d         | d         d| d         gfV  | dd          } t          | d          D ]&} dd| d         | d         | d         d| d         gfV  'd S rm   rq   rY   s    r   	vvcurvetoz+_GeneralizerDecombinerCommandsMap.vvcurveto   s      YY]]c$ii!ma''z$/?/?)?YY]a
Qa$q'47AtAwG	HHHH
qrr(4dA C Cd
47DGT!WaaA	BBBBBC Cr   c              #     K   t          |           dk     st          |           dz  dvrt          |           d }t          |           dz  dk    r*t          |           dz  dk    }| d d         | dd          }} t          | d          }	 	 t          |          } d	| d
         d
| d         | d         d
| d         gfV  t          |          } d	d
| d
         | d         | d         | d         d
gfV  g# t          $ r Y nw xY w|r\|} |r,d	| d
         d
| d         | d         | d         | d         gfV  d S d	d
| d
         | d         | d         | d         | d         gfV  d S d S Nrn      >   r   r   rn   rp   r*   r   rp   Trk   r   ro   r-   r
   rT   r0   rc   rC   	last_argslastStraightr8   s       r   	hvcurvetoz+_GeneralizerDecombinerCommandsMap.hvcurveto   s     YY]]c$ii!m944Jt<L<L6L)YY]ad))a-1$<#2#YRSS	4tQ"D88Da!T!Wd1gq$q'B
CCCC88DDGT!Wd1gtAwB
CCCC	D
 
   4 J
4 Ja!T!Wd1gtAwQH
IIIIIIDGT!Wd1gtAwQH
IIIIIIJ J   A(C4 4
D Dc              #     K   t          |           dk     st          |           dz  dvrt          |           d }t          |           dz  dk    r*t          |           dz  dk    }| d d         | dd          }} t          | d          }	 	 t          |          } d	d
| d
         | d         | d         | d         d
gfV  t          |          } d	| d
         d
| d         | d         d
| d         gfV  g# t          $ r Y nw xY w|r\|} |r,d	d
| d
         | d         | d         | d         | d         gfV  d S d	| d
         d
| d         | d         | d         | d         gfV  d S d S rv   ry   rz   s       r   	vhcurvetoz+_GeneralizerDecombinerCommandsMap.vhcurveto   s     YY]]c$ii!m944Jt<L<L6L)YY]ad))a-1$<#2#YRSS	4tQ"D88DDGT!Wd1gtAwB
CCCC88Da!T!Wd1gq$q'B
CCCC	D
 
   4 J
4 JDGT!Wd1gtAwQH
IIIIIIa!T!Wd1gtAwQH
IIIIIIJ Jr~   c              #      K   t          |           dk     st          |           dz  dk    rt          |           | d d         | dd          }} t          | d          D ]} d| fV  	d|fV  d S )Nrw   rj   r*   rk   r^   rq   rC   r{   s     r   
rcurvelinez,_GeneralizerDecombinerCommandsMap.rcurveline  s      YY]]c$ii!mq((
40@0@*@"ItBCCy	$dA  d
t		Ir   c              #      K   t          |           dk     st          |           dz  dk    rt          |           | d d         | dd          }} t          | d          D ]} d| fV  	d|fV  d S )Nrw   r*   r   ir^   rk   rq   r   s     r   
rlinecurvez,_GeneralizerDecombinerCommandsMap.rlinecurve  s      YY]]c$ii!mq((
40@0@*@"ItBCCy	$dA  d
T		i      r   N)__name__
__module____qualname__staticmethodr%   r#   r&   r^   re   rh   rk   rr   rt   r}   r   r   r    r   r   rV   rV      s}         , " " ," " " ,"   ,   ,   ,   , C C ,C C C ,C J J ,J* J J ,J,   , ! ! ,! ! !r   rV   c                    t          d | D                       rd | D             }n| }|d         }|d d         }t          |          |z  dz
  |dz   z  t          |          k    st          |           d |d |         D             }||d          t                    }fdt          d|          D             }d t	          ||          D             }|S )	Nc                 8    g | ]}t          |t                    S r   rI   rJ   s     r   
<listcomp>z)_convertBlendOpToArgs.<locals>.<listcomp>  s"    4443C		444r   c                 f    g | ].}t          |t                    rt          |          n|gD ]}|/S r   r   rA   _convertBlendOpToArgs)r   erS   s      r   r   z)_convertBlendOpToArgs.<locals>.<listcomp>  s`     A A A",Qt"4"4=A1#A AA1 A A A Ar   r   r   c                     g | ]}|gS r   r   rJ   s     r   r   z)_convertBlendOpToArgs.<locals>.<listcomp>/  s    222#222r   c                 *    g | ]}||z            S r   r   )r   rS   	deltaArgs
numRegionss     r   r   z)_convertBlendOpToArgs.<locals>.<listcomp>2  s'    ZZZqy1z>)*ZZZr   r   c                     g | ]
\  }}||z   S r   r   )r   abs      r   r   z)_convertBlendOpToArgs.<locals>.<listcomp>3  s     ===$!QA===r   )rL   r-   r
   rP   zip)		blendListrC   r:   defaultArgsnumDeltaValues	deltaList
blend_argsr   r   s	          @@r   r   r     s'   
 44)44455 A Ai A A A$$ 
$ "X 	SbS	$ii"Q&	JN	#s4yy	0	0922jyj!1222)**i..ZZZZZE!^Z4X4XZZZ==#k)"<"<===r   Fc                 "   g }t           }| D ]\  }}t          d |D                       rQ	 d |D             }nC# t          $ r6 |r0|                    d|f           |                    d|gf           n Y nw xY wt	          ||d           }|s|                    ||f           	  ||          D ]}|                    |           # t          $ r6 |r0|                    d|f           |                    d|gf           n Y w xY w|S )Nc                 8    g | ]}t          |t                    S r   rI   rJ   s     r   r   z&generalizeCommands.<locals>.<listcomp>;  s"    	0	0	0C*S$

	0	0	0r   c                 f    g | ].}t          |t                    rt          |          n|gD ]}|/S r   r   )r   rE   rR   s      r   r   z&generalizeCommands.<locals>.<listcomp>=  sH    hhh#jQTVZF[F[(f(=c(B(B(Bbeafhh!Ahhhhr   r+   )rV   rL   r
   r   getattr)r6   ignoreErrorsresultmappingrM   rC   funccommands           r   generalizeCommandsr   6  s   
, 
 
XR	0	04	0	0	011 
	hhhhhDD
     ]]B:]]B:
  
"d	#	#$	 	=="T

$t**  w
MM'	 
 
 
 
 MM2t*
MM2t*	 
 	s!   9=A98A9(#C=DDc                 R    t          t          t          | |          fi |          S r   )rN   r   r?   r   r1   kwargss      r   generalizeProgramr   X  -    ,->w-V-VaaZ`aabbbr   c                     | d         s | d         sd| dd         fS d| dd         fS | d         sd| dd         fS d| fS )ab  
	Takes X,Y vector v and returns one of r, h, v, or 0 depending on which
	of X and/or Y are zero, plus tuple of nonzero ones.  If both are zero,
	it returns a single zero still.

	>>> _categorizeVector((0,0))
	('0', (0,))
	>>> _categorizeVector((1,0))
	('h', (1,))
	>>> _categorizeVector((0,2))
	('v', (2,))
	>>> _categorizeVector((1,2))
	('r', (1, 2))
	r   r   0Nvhrr   )r   s    r   _categorizeVectorr   \  sg     	
! 		
1 
q!u*
qu*	
1 
q!u*
q&=r   c                 6    | dk    r|S |dk    r| S | |k    r| S d S )Nr   r   r   r   s     r   _mergeCategoriesr   v  s.    HHQhHHQhFF1Hr   c                 2    | dk    rdS | dk    rdS | dv sJ | S )Nr   r   0rr   )r   s    r   _negateCategoryr   |  s.    HHSSHHSS	T					r   c                    t          |           }d}g }d}||k     r^| |         }t          |t                    s!|                    |           |dz  }|dz  }n|}t          |          }|g}|dz  }|d|z   z  }||k     rpt          | |         t                    rU|                    | |                    |dz  }||z  }||z   t          k    rn!||k     rt          | |         t                    Ut          |          }	g }
|D ]}|
                    |d                    |D ]}|
                    |dd                      |
                    |	           |                    |
           ||	z   }||k     ^|S )Nr   r   )r-   r   rA   r   r   rB   )rC   num_args	stack_usenew_argsrS   rE   prev_stack_usenum_sources	blendlist
num_blendsr   s              r   _convertToBlendCmdsr     s    II8||Q#	C		 &+??361>99>
 S;u961K9
h,,JtAw55,T!WFAI;..  h,,JtAw55, I::  sc!f  sc!""gZ   ??:
*9Q 	8||T 	r   c                 f   t          |t                    rat          | t                    rHt          |           t          |          k    rt                      d t	          | |          D             S || }} t          | t                    r"t          | d         |          g| dd          z   S | |z   S )Nc                 4    g | ]\  }}t          ||          S r   )_addArgs)r   vavbs      r   r   z_addArgs.<locals>.<listcomp>  s&    
3
3
328B
3
3
3r   r   r   )r   rA   r-   r
   r   r   r   s     r   r   r     s    q$ 4 	!ffA
,,
3
3Q
3
3
33
Qa1q$ %
1Q4

	qu	$$	Ar   T0   c                 V   |rt          | |          } nt          |           } t          t          |           dz
  dd          D ]y}d| |         d         cxk    r| |dz
           d         k    rOn -| |dz
           d         | |         d         }}d|d         |d         z   |d         |d         z   gf| |dz
  <   | |= zt          t          |                     D ]}| |         \  }}	|dv r%t	          |	          \  }
}	|
|dd          z   |	f| |<   6|dk    rPt	          |	d d                   \  }}t	          |	d	d                    \  }}||z   d
z   ||	dd         z   |z   f| |<   |st          t          |           dz
  dd          D ]}| |         \  }}	|dk    r;t          |	          dk    sJ t	          |	dd                   \  }
}	|
dz   }||	f| |<   |dk    r| |= X|r|dv r|| |dz
           d         k    rs| |dz
           \  }}t          |	          dk    rt          |          dk    sJ 	 t          |	d         |d                   g}n# t          $ r Y w xY w||f| |dz
  <   | |= t          dt          |           dz
            D ]3}| |         \  }}	| |dz
           d         | |dz            d         }}|dv rM||cxk    rdk    r@n n=t          |	          dk    sJ |d         dk    r
d|	d         gn	|	d         dg}	d|	f| |<   |dd          d
k    rt          |	          dk    r||cxk    rdk    rn |d         dk    |d         dk    z  sJ |d         dk    rd}n |d         dk    rd}n|d         dk    rd}nd}|	d |          t          |	          d          z   |	|d          z   }	d|	f| |<   35t          t          |           dz
  dd          D ]}| |dz
           \  }}| |         \  }}d }||hddhk    r=||k    r|}n!|dk    rt          |          dk    rd}nt          |          dk    rd}n||fdv r|}n||hddhk    r|}nd
|dd          cxk    r|dd          k    rn n|d d         \  }}|d d         \  }}|dk    s|dk    s||cxk    rdk    rn nt          ||          }||dk    rt          ||          }|d|z   d
z   }nL|dk    r*t          |t          |                    }|.|dz   d
z   }nt          ||          }|K||z   d
z   }|r3t          |          t          |          z   |k     r|||z   f| |dz
  <   | |= t          t          |                     D ]A}| |         \  }}	|dv rd|dd          z   |	f| |<   %|dd          d
k    r|d d         dvr |d d         \  }}|dk    |dk    z  rt          |	          dz  dk    sJ |d k    rd}|d k    rd}|dk    r|}|dk    rt          |          }||hddhk    sJ ||f            t          |	          dz  rj||k    r>|dk    t          |	          d!z  dk    z  r |	d d	         |	dd          z   |	d	d         z   }	n&|dk    r |	dd         |	d d         z   |	dd          z   }	||z   d
z   |	f| |<   ACt          t          |                     D ]:}| |         \  }}	t          d" |	D                       r|t          |	          f| |<   ;| S )#N)r   r   r   r   r%   >   r^   r%   rk   r*   r   curvetorn   	00curvetoro   lineto0lineto>   re   rh   >   r   re   rh   r^   r   rp   r   )r   rj   r   r   >   r^   r   rk   r   rh   re   >   r   0movetor   >   hhhvrrvhvvr   rw   c              3   @   K   | ]}t          |t                    V  d S r   rI   rJ   s     r   r   z%specializeCommands.<locals>.<genexpr>  rK   r   )r   rA   rP   r-   r   r   r
   r.   r   r   rL   r   )r6   r   generalizeFirstpreserveTopologymaxstackrS   v1v2rM   rC   cc1args1c2args2_
other_argsr   prvnxtposop1op2new_opd0d1d2d3dop0s                                 r   specializeCommandsr     s,	   P  |DDD(((^^( HaB
'
'  Q(1+a.4444HQqSM!$444444QqSM!hqk!nr21beRU2a5[9:8AaC={` H

  QQK'"T!!!t$$71d2abb648A;; bqb**92u bcc++92uBy%QqS	/%"778A;	 8 	 Xq"b))  aqk82t 	Kt99>>>>QqS	**GAt	
8Bd(HQK 	Ioo 	 
R)))
hqsmAQqSMMAzt99>>c*oo2222$q':a=112XX   XNHQqSM 3x==?
#
#  QQK'"TQqSM!hqsmA.c#,,,1H1H1H1Hy1H1H1H1H1H
d))q....Q%3,,1d1g,,T!WaL4T"8A;VySYY!^^s0I0I0I0Ik0I0I0I0I0Ia5C<BqESL
))))esll
CC
1
CC
1
CC
C
tt*ztDzz$''
'$stt*
44t$8A; HaB
'
' / /Qqsm)#eqk)#e& 
3ZI{+++	SjjFF
kc%jjAooVV	UqVSzMMM66Szi+++66CG&&&&s122w&&&&&G62rG62rCii299bCB1iCiiBAy(U9_FF
c			"oa00	1	1B	z8VIFF	"b	!	!B	z8T)^F  E

SZZ'(22E%K(8AaC={ H

  QQK'"T!!!RVT!8A;VyRV+III!f83
czcSj! t99q=A	Sjj#	Sjj#	Sjj#	Sjj,,#s)Cy
 
 
 3*
 
 
 	$ii!m )
czz	D		A*+ -#2#YtBCCy be,ds

!A#YtBQBxQRR(dS"D(8A; H

 / /Qa[("d//$///// /(...8A;s   6I
I! I!c                 R    t          t          t          | |          fi |          S r   )rN   r   r?   r   s      r   specializeProgramr     r   r   __main__r   zProgram:z	Commands:zProgram from commands:zGeneralized program:zSpecialized program:r   )F)FTFr   )!__doc__fontTools.cffLibr   r   r   r?   rF   rN   rT   objectrV   r   r   r   r   r   r   r   r   r   r   r   sysr-   argvdoctestexittestmodfailedr   printr6   program2r   r   r   <module>r      s    + * * * * *   * * *R R R Rj  
 
 
  w! w! w! w! w! w! w! w!r! ! !F       Dc c c c  4  
 
 
1 1 1f
 
 
 	Y Y Y Yvc c c c zCMMQ...
#(?7?#$$$?38ABB<((zEE//'22333g&&{UU8___h''   %%(A(A"B"B"B8oo6G6G6P6P&Q&Q R R Roo6G6G6P6P&Q&Q R R R R R r   