
    jke
f                     v   d dl mZ d dlmZmZmZmZmZmZm	Z	m
Z
mZmZ d dl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mZmZ d d
lmZ d dlm Z  ddl!m"Z"m#Z#m$Z$m%Z% e"Z&e#Z'd Z(d Z)d Z*d Z+dZ,d Z-d Z.d Z/d Z0 edd      Z1d Z2d$dZ3d Z4d Z5 G d de      Z6 G d d e6      Z7 G d! d"e      Z8y#)%    )
namedtuple)
maxStackLimitTopDictIndex
buildOrdertopDictOperatorstopDictOperators2privateDictOperatorsprivateDictOperators2FDArrayIndexFontDictVarStoreData)BytesIO)specializeCommandscommandsToProgram)newTable)varLib)allEqual)	roundFunc)T2CharStringT2OutlineExtractor)T2CharStringPen)partial   )VarLibCFFDictMergeErrorVarLibCFFPointTypeMergeErrorVarLibCFFHintTypeMergeErrorVarLibMergeErrorc                    | d   }|j                   D cg c]  }|j                   }}t        j                  j	                  ||      }t        j                  j                  ||      }| d   j                  j                  d   }	t        |      |	_	        |	j                  d   j                  <|	j                  }
|
D ]*  }t        |d      s|	j                  |j                  _        , y y c c}w )NfvarCFF2r   )
otVarStorePrivate)axesaxisTagr   builderbuildVarRegionListbuildVarStorecfftopDictIndexr   VarStoreFDArrayvstorehasattrr"   )varFontvarModelvarDataListmasterSupports	fvarTableaxisaxisKeysvarTupleListvarStoreCFFVtopDictfdArrayfontDicts               6/usr/lib/python3/dist-packages/fontTools/varLib/cff.pyaddCFFVarStorer;   %   s    I)288H8>>44^XNL>>//kJLfo!!..q1G#|<Gq  (// 	;Hx+*1*:*:  '	; ) 9s   C,c                    | j                   j                  }t        d |d       }| j                  j                  |_        || _        |d   }t        |d      r|j                  }nd }t        t              }||_	        ||_
        t        |d      st               x}|_        d |_        |j                  |_        ||j                  _        |j                   }|j"                  r||j$                  _        n||_        t'               }	|	j)                  d       |j+                  |	       ||	_        t        t,              }
|/t.        D ]@  }|d   }||
vs||j0                  v r|j0                  |= t        ||      s5t3        ||       B n|j                  }t        t,              }
|D ]  }	|	j)                  d       t5        |	j0                  j7                               D ]7  }||	j                  vs|	j0                  |= t        |	|      s,t3        |	|       9 |	j                  }t.        D ]@  }|d   }||
vs||j0                  v r|j0                  |= t        ||      s5t3        ||       B  t8        D ]@  }|d   }||vs||j0                  v r|j0                  |= t        ||      s5t3        ||       B d| _        t=               }| j?                  ||d       |jA                  d       | jC                  ||d       y )Nr   r"   r+   Tr      )isCFF2)"otFontgetGlyphOrderr   r)   itemsr-   r"   r   r   ordercff2GetGlyphOrderr   r+   stringsGlobalSubrsr8   CharStringscharStringsAreIndexedcharStringsIndexr   setCFF2appendr
   r	   rawDictdelattrlistkeysr   majorr   compileseek	decompile)r(   r?   rC   topDictDatar7   privateDictopOrderr8   charStringsr9   privateOpOrderentrykeyfiles                 r:   lib_convertCFFToCFF2r[   4   s   

00t%6=K((..K"C!nGw	"oo*+GGM 1G7I&$0N2'/%11&-#)),,3:K((0")K:x &#$9:"- 2Ahn,k111'//4{C0S12 //#$9: 	2HT"H,,1134 /hnn, ((-x-#.	/ #**K- 2Ahn,k111'//4{C0S12	2& " &Ahggoo%OOC(w$%& CI9DKKfTK*IIaLMM$tM,    c                     | d   }t        |j                  |        t        d      }|j                  |_        || d<   | d= y NzCFF r    )r[   r(   r   )r.   cffTablenewCFF2s      r:   convertCFFtoCFF2ra      s>    vHw/vG,,GKGFOr\   c                 \    t        | t              r| j                         rt        |       S | S N)
isinstancefloat
is_integerint)nums    r:   conv_to_intri      s#    #u#.."23xJr\   )
BlueValues
OtherBluesFamilyBluesFamilyOtherBlues	BlueScale	BlueShiftBlueFuzzStdHWStdVW	StemSnapH	StemSnapVc                 R    | |   }||   }||v r||   }||   j                   }|S d }|S rc   )r"   )regionFDArraysfd_indexrifd_mapregion_fdArrayregion_fd_mapregion_fdIndexprivates           r:   get_privater~      sK    #B'N8$M	]&r* 088 N Nr\   c           
      $   | d   }| dd }t        |d   d      r|D cg c]  }|j                   }}n|D cg c]  }|g }}t        |j                        D ]P  \  }}	|	j                  }
t	        |
dd      }||   \  }}g }|j
                  dd D ]1  }|j
                  j                  |      dz
  }|j                  |       3 |
g}|
}|D ](  }t        ||||      }||}n|}|j                  |       * t        |      }|
j                  j                         D ]  \  }}g }|t        vrt        |t              r	 |D cg c]  }|j                  |    }}	 t%        | }	 dg|z  }d}|D ]`  }t        |      D cg c]  \  }}|||   z
   }}}|st+        |      sd	}|}|j-                  |      }|d   |d<   |j                  |       b |sQ|D  cg c]  } | d   	 }} n>|D cg c]  }|j                  |    }}t+        |      s|j-                  |      }n|d   }t        |t              rWt        |      D ]H  \  }}!t        |!t              r%t        |!      D ]  \  }"}#t/        |#      ||   |"<    ;t/        |!      ||<   J nt/        |      }||
j                  |<    S yc c}w c c}w c c}w # t        $ r t!        dj#                  |             Y w xY w# t&        $ r t)        |||      w xY wc c}}w c c} w c c}w )
a  
    I step through the FontDicts in the FDArray of the varfont TopDict.
    For each varfont FontDict:

    * step through each key in FontDict.Private.
    * For each key, step through each relevant source font Private dict, and
            build a list of values to blend.

    The 'relevant' source fonts are selected by first getting the right
    submodel using ``vsindex_dict[vsindex]``. The indices of the
    ``subModel.locations`` are mapped to source font list indices by
    assuming the latter order is the same as the order of the
    ``var_model.locations``. I can then get the index of each subModel
    location in the list of ``var_model.locations``.
    r   r   Nr+   vsindexz\Warning: {key} in default font Private dict is missing from another font, and was discarded.)rY   FT)r-   r+   	enumerater"   getattr	locationsindexrJ   r~   lenrK   rA   pd_blend_fieldsrd   rM   KeyErrorprintformatzip
IndexErrorr   r   	getDeltasri   )$	top_dictsvsindex_dict	var_modelry   r7   region_top_dicts	fdTopDictrv   rw   	font_dictprivate_dictr   	sub_model_master_indiceslocipdslast_pdrx   pdnum_mastersrY   valuedataListvaluesprev_val_listany_points_differval_listvalrel_listdeltasdataitemjjtems$                                       r:   merge_PrivateDictsr      s   " lG }"I.=MN	)++NN7GH)9+HH(9 Z1) ((,	15 $G,	1&&qr* 	%C##))#.2A!!!$	% n  	B^Xr6BB zJJrN	 #h&..446 C	1JCH/)%&8;<"bjjo<F<F &\F "#k 1$)! & ,HAJ8AT 5=a}Q// H   .x7I,0)$,M&00:F !)F1IOOF+, )4<=DQ=H=478b"**S/88'(226:H%ayH (D)(2 8GAt!$-'0 ?GAt-8->HQKN? '2$&78 'x0(0L  %GC	1/Z1 OH< = %%+VV_
  " F1#ufEEF$   >8sL   J.
J3 J=J8J=K(LL,L8J==$K%$K%(K?c                     d| v r| d   S | d   S r^    )fonts    r:   _cff_or_cff2r   !  s    ~F|<r\   c                    i }|d   }|dd }t        |      }t        |      j                  j                  d   }t	        |d      st        |      D ci c]  }|d c}|d<   |S i }|j                  }	|j                         }
t        |	      D ]  \  }}|||
|   <   ||vsi ||<    t        |      D ]  \  }}|j                         }t        |      j                  j                  d   }t	        |d      s||d      }d||   |<   U|j                  }t        |      D ]  \  }}|||      }||   }||vs|||<     |S c c}w )a  Since a subset source font may have fewer FontDicts in their
    FDArray than the default font, we have to match up the FontDicts in
    the different fonts . We do this with the FDSelect array, and by
    assuming that the same glyph will reference  matching FontDicts in
    each source font. We return a mapping from fdIndex in the default
    font to a dictionary which maps each master list index of each
    region font to the equivalent fdIndex in the region font.r   r   NFDSelect)	r   r   r(   r)   r-   ranger   r@   r   )r.   
fonts_listry   default_fontregion_fontsnum_regionsr7   rx   gname_mappingdefault_fdSelect
glyphOrdergidfdIndexregion_fontregion_glyphOrderregion_topDictdefault_fdIndexregion_fdSelect
region_maps                      r:   	getfd_mapr   '  s    Fa=Lab>Ll#K<(,,99!<G7J' &+;%78rRU8q	M''++-J!"23 !W)0jo&&  F7O! %\2 -K'557%k266CCAF~z2+,=a,@AO*+F?#B',55O )/ : -W"/0A#0F"G#O4
Z'%,JrN	-- M1 9s   
ECVarDataz'varDataList masterSupports vsindex_dictc                    | d   j                   j                  d   }|g|dd  D cg c]$  }t        |      j                   j                  d   & c}z   }t        |j                        }t        ||||      }t        | |      }	t        ||j                  ||	       t        | ||j                  |j                         y c c}w )Nr    r   r   )r(   r)   r   r   mappingmerge_charstringsr   r   r   r;   r0   r1   )
r.   modelordered_fonts_listr   r7   ttFontr   r   cvDatary   s
             r:   merge_region_fontsr   U  s    fo!!..q1G	?QRSRT?U5;V  --a0 I emm$Kz;	5IFw 23Fy&"5"5ufE7E6#5#5v7L7LMs   )B>c                 ,   || vry | |   }|r|j                          |j                  g k(  ry t        |j                        dk  rO|j                  d   dk(  r=t        |j                        dk(  s$t        |j                  d         t        t
        fv ry |S )Nr=   endcharr   r   )rR   programr   typerg   re   )charstrings	glyphNamefilterEmptycss       r:   _get_csr   a  s    #	Y	B
::

Oq 

2)+RZZA%bjjm)<e)LIr\   c                 0   g }| j                   dd  D ]7  }||vr|j                  |       |j                  |j                  |             9 t        j                  j                  |d d      }t        |      }	|	||<   | |gf||	<   |j                  |       |	S )Nr   F)supportsrJ   r   r   r%   buildVarDatar   )
r   rY   r1   r   vsindex_by_keyr0   varTupleIndexessupportvar_datar   s
             r:   _add_new_vsindexr   t  s     O>>!"% >.(!!'*~33G<=> ~~**?D%HH,G!N3"SENLx Nr\   c                 j   i }i }g }g }|d   j                   }t        |       D ]B  \  }	}
t        |      D cg c]  \  }}t        |j                   |
|dk7        ! }}}|j                  |      \  }}|d   }t	        g |
|d      }t
        |_        |j                  |       |dd  }t        |d      D ]2  \  }}|j                  |       t
        |_        |j                  |       4 |j                  |j                  |j                  |d      }|||
<   |s|j                  rd|j                  vrt        d |D              }	 ||   }|dk7  s2|dg|j                  d d E |sd	|z  }t!        ||||||       t#        |||
      }|S c c}}w # t        $ r t!        ||||||      }Y cw xY w)Nr   r   )startT)r}   globalSubrsr   optimizeblendc              3   $   K   | ]  }|d u 
 y wrc   r   ).0vs     r:   	<genexpr>z$merge_charstrings.<locals>.<genexpr>  s     2aATM2s   r   )T)r0   r1   r   )rF   r   r   getSubModelCFF2CharStringMergePenMergeOutlineExtractoroutlineExtractordrawrestartgetCharStringr}   r   seen_movetor   tupler   r   r   )r   r   r   masterModelr   r   r0   r1   default_charstringsr   gnamer   tdall_csr   model_csdefault_charstringvar_pen	region_cs
region_idxregion_charstringnew_csrY   r   r   s                            r:   r   r     s   LNKN#A,22
+ 66
U AJ)@T
7<q"GBNNE162
 
 &11&9x &a[(UKC /D+( QRL	-6y-J 	,)J)OOJ'1F.""7+	, &&&..*66	 ' 
 &,E"##)F  2622	$S)G a<")9!5FNN2Am66v #nlNK	
 %!F MK
Z  	&sNL.+G	s   $F	FF21F2c                       e Zd ZdZddZy)CFFToCFF2OutlineExtractorzThis class is used to remove the initial width from the CFF
    charstring without trying to add the width to self.nominalWidthX,
    which is None.c                     | j                         }| j                  s.|t        |      dz  z  r|dd  }| j                  | _        d| _        |S )Nr=   r   )popallgotWidthr   defaultWidthXwidth)selfevenOddargss      r:   popallWidthz%CFFToCFF2OutlineExtractor.popallWidth  sH    {{}}}#d)a-(ABx++DJDMr\   N)r   )__name__
__module____qualname____doc__r  r   r\   r:   r   r     s    r\   r   c                   ^     e Zd ZdZ	 	 d fd	Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Z xZS )r   zUsed to extract the charstring commands - including hints - from a
    CFF charstring in order to merge it as another set of region data
    into a CFF2 variable font charstring.c           	      0    t         |   |||||||       y rc   )super__init__)	r  pen
localSubrsr   nominalWidthXr   r}   blender	__class__s	           r:   r  zMergeOutlineExtractor.__init__  s"     	[-QX	
r\   c                 f    | j                         }| j                  t        |      dz  z   | _        |S )Nr=   )r  	hintCountr   )r  r  s     r:   
countHintsz MergeOutlineExtractor.countHints  s-    !#d)q.8r\   c                 <    | j                   j                  ||       y rc   )r  add_hint)r  r   r  s      r:   _hint_opzMergeOutlineExtractor._hint_op  s    $%r\   c                 H    | j                         }| j                  d|       y )Nhstemr  r  r  r   r  s      r:   op_hstemzMergeOutlineExtractor.op_hstem       gt$r\   c                 H    | j                         }| j                  d|       y )Nvstemr  r  s      r:   op_vstemzMergeOutlineExtractor.op_vstem  r  r\   c                 H    | j                         }| j                  d|       y )Nhstemhmr  r  s      r:   
op_hstemhmz MergeOutlineExtractor.op_hstemhm       i&r\   c                 H    | j                         }| j                  d|       y )Nvstemhmr  r  s      r:   
op_vstemhmz MergeOutlineExtractor.op_vstemhm
  r%  r\   c                     | j                   s;| j                         }|r| j                  d|       | j                  dz   dz  | _         | j                  d   j                  || j                         \  }}||fS )Nr'        r   )hintMaskBytesr  r  r  callingStackgetBytes)r  r   r  r,  s       r:   _get_hintmaskz#MergeOutlineExtractor._get_hintmask  sq    !!??$Di."&..1"4!:D#004==eTEWEWXum##r\   c                 l    | j                  |      \  }}| j                  j                  d|g       ||fS )Nhintmaskr/  r  add_hintmaskr  r   r,  s      r:   op_hintmaskz!MergeOutlineExtractor.op_hintmask  8    #11%8}j=/:e##r\   c                 l    | j                  |      \  }}| j                  j                  d|g       ||fS )Ncntrmaskr2  r4  s      r:   op_cntrmaskz!MergeOutlineExtractor.op_cntrmask  r6  r\   )NN)r  r  r  r	  r  r  r  r  r!  r$  r(  r/  r5  r9  __classcell__r  s   @r:   r   r     sB    - 

&%%''$$
$r\   r   c                   r     e Zd ZdZ	 d f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dZ xZS )r   z Pen to merge Type 2 CharStrings.c                     t         |   d d d|       d| _        || _        || _        || _        d| _        d| _        || _        t        |t              | _
        y )NT)r  glyphSetr    roundTolerancer   Fround)r  r  pt_index	_commandsm_indexr   prev_move_idxr   r   r   rA  )r  default_commandsr   r   
master_idxr?  r  s         r:   r  zCFF2CharStringMergePen.__init__%  sd     	D 	 	
 )!& "~U;
r\   c                 X   | j                   dk(  r| j                  j                  ||gg       ng| j                  | j                     }|d   |k7  r2t	        || j                  t        |d         |d   | j                        |d   j                  |       | xj                  dz  c_        y Nr   r   )rD  rC  rJ   rB  r   r   r   )r  
point_type	pt_coordscmds       r:   	add_pointz CFF2CharStringMergePen.add_point5  s    <<1NN!!:	{";<../C1v#2s3q6{CFDNN  FMM)$r\   c                 X   | j                   dk(  r| j                  j                  ||gg       ng| j                  | j                     }|d   |k7  r2t	        || j                  t        |d         |d   | j                        |d   j                  |       | xj                  dz  c_        y rI  rD  rC  rJ   rB  r   r   r   )r  	hint_typer  rL  s       r:   r  zCFF2CharStringMergePen.add_hintA  s    <<1NN!!9tf"56../C1v"1t}}c#a&k3q64>>  FMM$r\   c                    | j                   dk(  r<| j                  j                  |g g       | j                  j                  d|gg       n| j                  | j                     }|d   |k7  r2t	        || j                  t        |d         |d   | j                        | xj                  dz  c_        | j                  | j                     }|d   j                  |       | xj                  dz  c_        y )Nr    r   rO  )r  rP  abs_argsrL  s       r:   r3  z#CFF2CharStringMergePen.add_hintmaskM  s    
 <<1NN!!9b/2NN!!2z"23../C1v"1t}}c#a&k3q64>>  MMQM../CFMM(#r\   c                     | j                   sd| _         | j                  |      }| j                  d|       | j                  dz
  | _        y )NTrmovetor   )r   _prM  rB  rE  r  ptrK  s      r:   _moveTozCFF2CharStringMergePen._moveTo`  sA    #DGGBK	y), "]]Q.r\   c                 J    | j                  |      }| j                  d|       y )NrlinetorV  rM  rW  s      r:   _lineTozCFF2CharStringMergePen._lineToi  s    GGBK	y),r\   c                 t    | j                   } ||       ||      z    ||      z   }| j                  d|       y )N	rrcurvetor\  )r  pt1pt2pt3rV  rK  s         r:   _curveToOnez"CFF2CharStringMergePen._curveToOnem  s4    WWsGbg%3/	{I.r\   c                      y rc   r   r  s    r:   
_closePathz!CFF2CharStringMergePen._closePathr      r\   c                      y rc   r   re  s    r:   _endPathzCFF2CharStringMergePen._endPathu  rg  r\   c                 .    d| _         || _        d| _        y )Nr   )r   r   )rB  rD  _p0)r  r   s     r:   r   zCFF2CharStringMergePen.restartx  s    !r\   c                     | j                   S rc   )rC  re  s    r:   getCommandsz"CFF2CharStringMergePen.getCommands}  s    ~~r\   c                    |D ]  }|d   }t        | }t        |      |d<    d}|D ]  }|d   }|dv r1t        |d         }t        |      st        d      |d   d   g|d<   ni|d   }	g }
|	D ]X  }t        |      r|
j	                  |d          # ||      dd }|d   g|z   }|j	                  d       |
j	                  |       Z |
|d<   |} |S )a  
        We first re-order the master coordinate values.
        For a moveto to lineto, the args are now arranged as::

                [ [master_0 x,y], [master_1 x,y], [master_2 x,y] ]

        We re-arrange this to::

                [	[master_0 x, master_1 x, master_2 x],
                        [master_0 y, master_1 y, master_2 y]
                ]

        If the master values are all the same, we collapse the list to
        as single value instead of a list.

        We then convert this to::

                [ [master_0 x] + [x delta tuple] + [numBlends=1]
                  [master_0 y] + [y delta tuple] + [numBlends=1]
                ]
        r   Nr   )r1  r8  z3Hintmask values cannot differ between source fonts.)r   rM   r   r   rJ   )r  commandsget_delta_funcrL  r  m_argslastOpopcoordcoords
new_coordsr   s               r:   reorder_blend_argsz)CFF2CharStringMergePen.reorder_blend_args  s    ,  	"Cq6D$ZF &\CF	"  	CQB 11SV*M   (1+AQ
# 1E"))%(3 "0!6qr!:!&q
V 3Q"))%01 $AF1	2 r\   c                     | j                   }| j                  |t        |j                  | j                              }|rt        |dt              }t        |      }t        |||      }|S )Nr@  F)generalizeFirstmaxstack)r   r}   r   )	rC  rw  r   r   rA  r   r   r   r   )r  r}   r   r   r   ro  r   
charStrings           r:   r   z$CFF2CharStringMergePen.getCharString  sn     >>**gi11D
 )%-H $H-!W+

 r\   )g{Gz?)NNNT)r  r  r  r	  r  rM  r  r3  rY  r]  rc  rf  ri  r   rm  rw  r   r:  r;  s   @r:   r   r   "  sV    * TX< 

&/-/

7t HLr\   r   N)F)9collectionsr   fontTools.cffLibr   r   r   r   r   r	   r
   r   r   r   ior   fontTools.cffLib.specializerr   r   fontTools.ttLibr   	fontToolsr   fontTools.varLib.modelsr   fontTools.misc.roundToolsr   fontTools.misc.psCharStringsr   r   fontTools.pens.t2CharStringPenr   	functoolsr   errorsr   r   r   r   MergeDictErrorMergeTypeErrorr;   r[   ra   ri   r   r~   r   r   r   r   r   r   r   r   r   r   r   r   r\   r:   <module>r     s    "    N $  , / I :   )-;L-^q1h(V j"KL	N& M` 2 <$5 <$~f_ fr\   