B
    Jd5T                 @   sr  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d Z(dd Z)dd Z*dd Z+dZ,dd Z-dd Z.dd Z/dd Z0edd Z1d!d" Z2d#d$ Z3d%d& Z4d'd( Z5G d)d* d*eZ6G d+d, d,e6Z7G d-d. d.eZ8d/S )0    )
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             C   s   | d }dd |j D }tj||}tj||}| d jjd }t|d|_|j	d j
d kr|j	}	x |	D ]}
t|
drl|j|
j_
qlW d S )NZfvarc             S   s   g | ]
}|j qS  )ZaxisTag).0Zaxisr   r   F/var/www/html/venv/lib/python3.7/site-packages/fontTools/varLib/cff.py
<listcomp>%   s    z"addCFFVarStore.<locals>.<listcomp>CFF2r   )Z
otVarStorePrivate)Zaxesr   builderZbuildVarRegionListZbuildVarStorecfftopDictIndexr   ZVarStoreFDArrayZvstorehasattrr"   )varFontZvarModelvarDataListmasterSupportsZ	fvarTableZaxisKeysZvarTupleListZvarStoreCFFVtopDictfdArrayfontDictr   r   r   addCFFVarStore#   s    

r.   c             C   s^  | j j}td |d }| jj|_|| _|d }t|dr>|j}nd }tt}||_	||_
t|dst  }|_d |_|j|_||j_|j}|jr||j_n||_t }	|	d ||	 ||	_tt}
|d k	rxDtD ]<}|d }||
kr||jkr |j|= t||rt|| qW n|j}tt}
x|D ]}	|	d xBt|	j D ]0}||	j	krL|	j|= t|	|rLt|	| qLW |	j}xJtD ]B}|d }||
kr||jkr|j|= t||rt|| qW q.W xJtD ]B}|d }||kr||jkr|j|= t||rt|| qW d| _t }| j||dd | d | j!||dd d S )Nr   r"   r&   Tr      )ZisCFF2)"otFontgetGlyphOrderr   r%   itemsr'   r"   r   r   ordercff2GetGlyphOrderr
   r&   stringsZGlobalSubrsr,   CharStringsZcharStringsAreIndexedZcharStringsIndexr   ZsetCFF2appendr	   r   rawDictdelattrlistkeysr   majorr   compileseekZ	decompile)r$   r0   r4   ZtopDictDatar+   ZprivateDictZopOrderr,   ZcharStringsr-   ZprivateOpOrderentrykeyfiler   r   r   lib_convertCFFToCFF22   s|    














rB   c             C   s6   | d }t |j|  td}|j|_|| d< | d= d S )NzCFF r!   )rB   r$   r   )r(   ZcffTableZnewCFF2r   r   r   convertCFFtoCFF2   s    rC   c             C   s   t | tr|  rt| S | S )N)
isinstancefloat
is_integerint)numr   r   r   conv_to_int   s    rI   )Z
BlueValuesZ
OtherBluesZFamilyBluesZFamilyOtherBluesZ	BlueScaleZ	BlueShiftZBlueFuzzZStdHWZStdVWZ	StemSnapHZ	StemSnapVc             C   s4   | | }|| }||kr,|| }|| j }nd }|S )N)r"   )regionFDArraysfd_indexrifd_mapZregion_fdArrayZregion_fd_mapZregion_fdIndexprivater   r   r   get_private   s    rO   c          
      s  | d }| dd }t |d dr2dd |D }ndd |D }xt|jD ]\}}|j}	t|	dd}
||
 \}}g }x0|jdd D ]}|j|d }|| qW |	g}|	}x6|D ].}t||||}|dkr|}n|}|| qW t	|}x|	j
 D ]\ }g } tkr qt|tr y fd	d|D }W n* tk
rl   td
j d wY nX yt| }W n" tk
r   t ||Y nX dg| d}x\|D ]T}fddt|D }|st|sd}|||}|d |d< || qW |sPdd |D }n0 fdd|D }t|sH||}n|d }t|trxbt|D ]L\}}t|trx4t|D ]\}}t||| |< qW nt|||< qfW nt|}||	j
 < qW qNW dS )aw  
	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&   c             S   s   g | ]
}|j qS r   )r&   )r   	fdTopDictr   r   r   r       s    z&merge_PrivateDicts.<locals>.<listcomp>c             S   s   g | ]
}|gqS r   r   )r   rP   r   r   r   r       s    vsindexc                s   g | ]}|j   qS r   )r8   )r   pd)r@   r   r   r       s    z\Warning: {key} in default font Private dict is missing from another font, and was discarded.)r@   Fc                s   g | ]\}}| |  qS r   r   )r   ival)prev_val_listr   r   r       s   Tc             S   s   g | ]}|d  qS )r   r   )r   datar   r   r   r       s    c                s   g | ]}|j   qS r   )r8   )r   rR   )r@   r   r   r       s    )r'   	enumerater&   r"   getattr	locationsindexr7   rO   lenr8   r2   pd_blend_fieldsrD   r:   KeyErrorprintformatzip
IndexErrorr   r   	getDeltasrI   )	top_dictsvsindex_dict	var_modelrM   r+   Zregion_top_dictsrJ   rK   Z	font_dictZprivate_dictrQ   Z	sub_model_Zmaster_indiceslocrS   ZpdsZlast_pdrL   rR   num_mastersvalueZdataListvaluesZany_points_differZval_listrel_listdeltasitemjZjtemr   )r@   rU   r   merge_PrivateDicts   s~    








ro   c             C   s   d| kr| d S | d S )NzCFF r!   r   )Zfontr   r   r   _cff_or_cff2  s    rp   c             C   s.  i }|d }|dd }t |}t|jjd }t|dsTdd t|D |d< |S i }|j}| }	x0t|D ]$\}
}|||	|
 < ||krpi ||< qpW xt|D ]\}}| }t|jjd }t|ds||d  }d|| |< q|j}x8t|D ],\}
}|||
  }|| }||kr|||< qW qW |S )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FDSelectc             S   s   i | ]
}d |qS )r   r   )r   rL   r   r   r   
<dictcomp>*  s    zgetfd_map.<locals>.<dictcomp>)	r[   rp   r$   r%   r'   rangerq   r1   rW   )r(   Z
fonts_listrM   Zdefault_fontZregion_fontsZnum_regionsr+   Zgname_mappingZdefault_fdSelect
glyphOrdergidZfdIndexrL   Zregion_fontZregion_glyphOrderZregion_topDictZdefault_fdIndexZregion_fdSelectZ
region_mapr   r   r   	getfd_map  s8    

rv   CVarDataz'varDataList masterSupports vsindex_dictc       	      C   st   | d j jd }|gdd |dd  D  }t|j}t||||}t| |}t||j|| t| ||j	|j
 d S )Nr!   r   c             S   s   g | ]}t |jjd  qS )r   )rp   r$   r%   )r   ZttFontr   r   r   r    I  s   z&merge_region_fonts.<locals>.<listcomp>r   )r$   r%   r[   mappingmerge_charstringsrv   ro   rd   r.   r)   r*   )	r(   modelZordered_fonts_listrt   r+   rc   rh   cvDatarM   r   r   r   merge_region_fontsF  s    


r|   c             C   s   || krd S | | S )Nr   )Zcharstrings	glyphNamer   r   r   _get_csT  s    r~   c       
      C   sz   g }x8| j dd  D ]&}||kr*|| ||| qW tj|d d}t|}	|	||< | |gf||	< || |	S )Nr   F)Zsupportsr7   rZ   r   r#   ZbuildVarDatar[   )
rz   r@   r*   rd   vsindex_by_keyr)   ZvarTupleIndexesZsupportZvar_datarQ   r   r   r   _add_new_vsindexY  s    

r   c                s  i }i }g }g }|d j }xFt| D ]8\}	  fdd|D }
tdd |
D dkrZq&||
\}}|d }tg  |d}t|_|| |dd  }x2t|ddD ]"\}}|| t|_|| qW |j	|j
|j|dd}|| < |jr&d	|jkrq&td
d |
D }y|| }W n( tk
rD   t||||||}Y nX |dkr&|dg|jd d< q&W |sd| }t|||||| t|||d}|S )Nr   c                s   g | ]}t |j qS r   )r~   r6   )r   td)gnamer   r   r    p  s   z%merge_charstrings.<locals>.<listcomp>c             S   s   g | ]}|d k	r|qS )Nr   )r   gsr   r   r   r    r  s    r   )startT)rN   globalSubrsre   optimizeblendc             s   s   | ]}|d k	V  qd S )Nr   )r   vr   r   r   	<genexpr>  s    z$merge_charstrings.<locals>.<genexpr>rQ   )T)r)   r*   rd   )r6   rW   r[   ZgetSubModelCFF2CharStringMergePenMergeOutlineExtractorZoutlineExtractorZdrawrestartgetCharStringrN   r   seen_movetoprogramtupler]   r   rw   )rt   rh   rc   ZmasterModelrd   r   r)   r*   Zdefault_charstringsru   Zall_csrz   Zmodel_csZdefault_charstringZvar_penZ	region_cs
region_idxZregion_charstringZnew_csr@   rQ   r{   r   )r   r   ry   g  sT    






ry   c               @   s   e Zd ZdZdddZdS )CFFToCFF2OutlineExtractorz This class is used to remove the initial width from the CFF
	charstring without trying to add the width to self.nominalWidthX,
	which is None. r   c             C   s<   |   }| js8|t|d A r*|dd  }| j| _d| _|S )Nr/   r   )ZpopallZgotWidthr[   defaultWidthXwidth)selfZevenOddargsr   r   r   popallWidth  s    z%CFFToCFF2OutlineExtractor.popallWidthN)r   )__name__
__module____qualname____doc__r   r   r   r   r   r     s   r   c                   sj   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Z  ZS )r   z Used 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.Nc          	      s   t  ||||||| d S )N)super__init__)r   penZ
localSubrsr   ZnominalWidthXr   rN   Zblender)	__class__r   r   r     s    
zMergeOutlineExtractor.__init__c             C   s    |   }| jt|d  | _|S )Nr/   )r   	hintCountr[   )r   r   r   r   r   
countHints  s    z MergeOutlineExtractor.countHintsc             C   s   | j || d S )N)r   add_hint)r   typer   r   r   r   _hint_op  s    zMergeOutlineExtractor._hint_opc             C   s   |   }| d| d S )NZhstem)r   r   )r   rZ   r   r   r   r   op_hstem  s    zMergeOutlineExtractor.op_hstemc             C   s   |   }| d| d S )NZvstem)r   r   )r   rZ   r   r   r   r   op_vstem  s    zMergeOutlineExtractor.op_vstemc             C   s   |   }| d| d S )NZhstemhm)r   r   )r   rZ   r   r   r   r   
op_hstemhm  s    z MergeOutlineExtractor.op_hstemhmc             C   s   |   }| d| d S )Nvstemhm)r   r   )r   rZ   r   r   r   r   
op_vstemhm  s    z MergeOutlineExtractor.op_vstemhmc             C   sN   | j s.|  }|r| d| | jd d | _ | jd || j \}}||fS )Nr         )hintMaskBytesr   r   r   ZcallingStackZgetBytes)r   rZ   r   r   r   r   r   _get_hintmask  s    z#MergeOutlineExtractor._get_hintmaskc             C   s&   |  |\}}| jd|g ||fS )Nhintmask)r   r   add_hintmask)r   rZ   r   r   r   r   op_hintmask  s    z!MergeOutlineExtractor.op_hintmaskc             C   s&   |  |\}}| jd|g ||fS )Ncntrmask)r   r   r   )r   rZ   r   r   r   r   op_cntrmask  s    z!MergeOutlineExtractor.op_cntrmask)NN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   )r   r   r     s   
r   c                   s   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zd ddZ  ZS )!r   z"Pen to merge Type 2 CharStrings.
	{Gz?c                sP   t  jd d d|d d| _|| _|| _|| _d| _d| _|| _t	|t
d| _
d S )NT)r   ZglyphSetr!   roundTolerancer   F)round)r   r   pt_index	_commandsm_indexrh   prev_move_idxr   r}   r   r   )r   Zdefault_commandsr}   rh   Z
master_idxr   )r   r   r   r     s    zCFF2CharStringMergePen.__init__c             C   sv   | j dkr| j||gg nF| j| j }|d |krVt|| jt|d |d | j|d | |  jd7  _d S )Nr   r   )r   r   r7   r   r   r[   r}   )r   Z
point_type	pt_coordscmdr   r   r   	add_point  s    
z CFF2CharStringMergePen.add_pointc             C   sv   | j dkr| j||gg nF| j| j }|d |krVt|| jt|d |d | j|d | |  jd7  _d S )Nr   r   )r   r   r7   r   r   r[   r}   )r   	hint_typer   r   r   r   r   r     s    
zCFF2CharStringMergePen.add_hintc             C   s   | j dkr.| j|g g | jd|gg n`| j| j }|d |krft|| jt|d |d | j|  jd7  _| j| j }|d | |  jd7  _d S )Nr    r   )r   r   r7   r   r   r[   r}   )r   r   Zabs_argsr   r   r   r   r      s    
z#CFF2CharStringMergePen.add_hintmaskc             C   s2   | j sd| _ | |}| d| | jd | _d S )NTZrmovetor   )r   _pr   r   r   )r   ptr   r   r   r   _moveTo2  s
    
zCFF2CharStringMergePen._moveToc             C   s   |  |}| d| d S )NZrlineto)r   r   )r   r   r   r   r   r   _lineTo;  s    
zCFF2CharStringMergePen._lineToc             C   s.   | j }|||| || }| d| d S )NZ	rrcurveto)r   r   )r   Zpt1Zpt2Zpt3r   r   r   r   r   _curveToOne?  s    z"CFF2CharStringMergePen._curveToOnec             C   s   d S )Nr   )r   r   r   r   
_closePathD  s    z!CFF2CharStringMergePen._closePathc             C   s   d S )Nr   )r   r   r   r   _endPathG  s    zCFF2CharStringMergePen._endPathc             C   s   d| _ || _d| _d S )Nr   )r   r   )r   r   Z_p0)r   r   r   r   r   r   J  s    zCFF2CharStringMergePen.restartc             C   s   | j S )N)r   )r   r   r   r   getCommandsO  s    z"CFF2CharStringMergePen.getCommandsc             C   s   x(|D ] }|d }t | }t||d< qW d}x|D ]}|d }|dkrxt|d }t|sdtd|d d g|d< nl|d }	g }
xV|	D ]N}t|r|
|d  q||dd }|d g| }|d |
| qW |
|d< |}q4W |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   )r   r   z3Hintmask values cannot differ between source fonts.)r`   r:   r   r   r7   )r   commandsZget_delta_funcr   r   Zm_argsZlastOpopZcoordZcoordsZ
new_coordsrl   r   r   r   reorder_blend_argsR  s0    



z)CFF2CharStringMergePen.reorder_blend_argsNTc             C   sJ   | j }| |t|j| jd}|r0t|dtd}t|}t|||d}|S )N)r   F)ZgeneralizeFirstZmaxstack)r   rN   r   )	r   r   r   rb   r   r   r   r   r   )r   rN   r   re   r   r   r   Z
charStringr   r   r   r     s    z$CFF2CharStringMergePen.getCharString)r   )NNNT)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r     s   	8 r   N)9collectionsr   ZfontTools.cffLibr   r   r   r   r   r   r	   r
   r   r   ior   ZfontTools.cffLib.specializerr   r   ZfontTools.ttLibr   Z	fontToolsr   ZfontTools.varLib.modelsr   ZfontTools.misc.roundToolsr   ZfontTools.misc.psCharStringsr   r   ZfontTools.pens.t2CharStringPenr   	functoolsr   errorsr   r   r   r   ZMergeDictErrorZMergeTypeErrorr.   rB   rC   rI   r\   rO   ro   rp   rv   rw   r|   r~   r   ry   r   r   r   r   r   r   r   <module>   s<   0O
r+
H7