U
    i2e#@                    @   s  d Z ddlZddlmZ ddlmZ ddlmZ ddl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mZ ddlmZ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!m"Z" ddl#m$Z$m%Z% ddl&Z&ddl'Z'ddl(m)Z)m*Z*m+Z+m,Z,m-Z- e)rddl.m/Z/ e&0e1Z2G dd de3Z4G dd de3Z5G dd de3Z6G dd de6Z7G dd de6Z8G dd de3Z9G dd  d e6Z:G d!d" d"e6Z;G d#d$ d$eZ<G d%d& d&e<Z=G d'd( d(e<Z>G d)d* d*e<Z?G d+d, d,eZ@d-ZAG d.d/ d/e"d0ZBG d1d2 d2eZCG d3d4 d4eZDG d5d6 d6eZEG d7d8 d8eZFG d9d: d:eZGG d;d< d<eZHG d=d> d>eZIG d?d@ d@eZJG dAdB dBeZKG dCdD dDeZLG dEdF dFeZMG dGdH dHeZNG dIdJ dJe"d0ZOG dKdL dLe"d0ZPG dMdN dNeZQG dOdP dPeZRG dQdR dReZSG dSdT dTe"d0ZTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcddZUdedf ZVdgdh ZWdidj ZXdkdl ZYdmdn ZZdodp Z[eWeXeYdqeZe[drdsZ\dtdu Z]dvdw Z^e^  dxdy Z_dS )zzfontTools.ttLib.tables.otTables -- A collection of classes representing the various
OpenType subtables.

Most are constructed upon import from data in otData.py, all are populated with
converter objects from otConverters.py.
    N)IntEnum)reduce)radians)defaultdict
namedtuple)dfs_base_table)quantizeRect)otRound)	TransformIdentity)	bytesjoinpadsafeEval)ControlBoundsPen)TransformPen   )	BaseTableFormatSwitchingBaseTableValueRecordCountReference getFormatSwitchingBaseTableClass)LookupDebugInfoLOOKUP_DEBUG_INFO_KEY)TYPE_CHECKINGIteratorListOptionalSet)_TTGlyphSetc                   @   s   e Zd Zdd ZdS )AATStateTablec                 C   s   i | _ g | _g | _d S N)ZGlyphClassesZStatesZPerGlyphLookupsself r#   C/tmp/pip-unpacked-wheel-txsm8jh_/fontTools/ttLib/tables/otTables.py__init__)   s    zAATStateTable.__init__N__name__
__module____qualname__r%   r#   r#   r#   r$   r   (   s   r   c                   @   s   e Zd Zdd ZdS )AATStatec                 C   s
   i | _ d S r    )Transitionsr!   r#   r#   r$   r%   0   s    zAATState.__init__Nr&   r#   r#   r#   r$   r*   /   s   r*   c                   @   s,   e Zd ZdZedd Zdd Zdd ZdS )	AATActionNc                 C   s   dS )N)NNr#   )fontstatesr#   r#   r$   compileActions7   s    zAATAction.compileActionsc                    s^    fdd j D }|r4|jdd|d |   jdkrZ|jdd j d |  d S )	Nc                    s   g | ]} j | r|qS r#   )__dict__.0fr!   r#   r$   
<listcomp><   s     
 z.AATAction._writeFlagsToXML.<locals>.<listcomp>Flags,valuer   ReservedFlagsz0x%04X)_FLAGS	simpletagjoinnewliner9   )r"   	xmlWriterflagsr#   r!   r$   _writeFlagsToXML;   s    
zAATAction._writeFlagsToXMLc                 C   s$   || j kstd| d| j|< d S )Nzunsupported flag %sT)r:   AssertionErrorr0   r"   flagr#   r#   r$   _setFlagD   s    zAATAction._setFlag)r'   r(   r)   r:   staticmethodr/   r@   rD   r#   r#   r#   r$   r,   4   s
   
	r,   c                   @   sl   e Zd ZdZdZdddgZdddd	d
ddddddddddddZdd Zdd Zdd Z	dd Z
dd  Zd!S )"RearrangementMorphAction   r   	MarkFirstDontAdvanceMarkLastz	no changeu	   Ax ⇒ xAu	   xD ⇒ Dxu   AxD ⇒ DxAu   ABx ⇒ xABu   ABx ⇒ xBAu   xCD ⇒ CDxu   xCD ⇒ DCxu   AxCD ⇒ CDxAu   AxCD ⇒ DCxAu   ABxD ⇒ DxABu   ABxD ⇒ DxBAu   ABxCD ⇒ CDxABu   ABxCD ⇒ CDxBAu   ABxCD ⇒ DCxABu   ABxCD ⇒ DCxBA)r   r         rG               	   
                  c                 C   s(   d| _ d| _d| _d| _d| _d| _d S Nr   F)NewStateVerbrH   rI   rJ   r9   r!   r#   r#   r$   r%   a   s    z!RearrangementMorphAction.__init__c                 C   sz   |d kst || j | jdkr,| jdks6t | j| j| jB }| jrP|dO }| jr^|dO }| jrl|dO }|| d S )Nr   rW       @      )rA   writeUShortrY   rZ   r9   rH   rI   rJ   r"   writerr-   actionIndexr?   r#   r#   r$   compilei   s    z RearrangementMorphAction.compilec                 C   s`   |d kst | | _| }|d@ | _t|d@ | _t|d@ | _t|d@ | _|d@ | _d S )NrW   r[   r\   r]   i  )	rA   
readUShortrY   rZ   boolrH   rI   rJ   r9   r"   readerr-   actionReaderr?   r#   r#   r$   	decompilev   s    

z"RearrangementMorphAction.decompilec                 C   s   |j |f| |  |jd| jd |  | | |jd| jd | j| j}|d k	rh|| |  |	| |  d S )NrY   r7   rZ   )
begintagr=   r;   rY   r@   rZ   _VERBSgetcommentendtag)r"   r>   r-   attrsnameZverbCommentr#   r#   r$   toXML   s    


zRearrangementMorphAction.toXMLc           	      C   s   d | _  | _| _d | _ | _| _dd |D }|D ]|\}}}|dkrXt|d | _ q6|dkrpt|d | _q6|dkrt|d | _q6|d	kr6|d d
D ]}| |	  qq6d S )Nr   Fc                 S   s   g | ]}t |tr|qS r#   
isinstancetupler2   tr#   r#   r$   r4      s     
 z4RearrangementMorphAction.fromXML.<locals>.<listcomp>rY   r8   rZ   r9   r5   r6   )
rY   rZ   r9   rH   rI   rJ   r   splitrD   strip	r"   ro   rn   contentr-   eltNameeltAttrs
eltContentrC   r#   r#   r$   fromXML   s    z RearrangementMorphAction.fromXMLN)r'   r(   r)   
staticSizeactionHeaderSizer:   rj   r%   rb   rh   rp   r}   r#   r#   r#   r$   rF   I   s2   

rF   c                   @   sD   e Zd ZdZdZddgZdd Zdd Zd	d
 Zdd Z	dd Z
dS )ContextualMorphActionrP   r   SetMarkrI   c                 C   s(   d| _ d\| _| _d| _d\| _| _d S )Nr   FF  r   )rY   r   rI   r9   	MarkIndexCurrentIndexr!   r#   r#   r$   r%      s    zContextualMorphAction.__init__c                 C   s`   |d kst || j | j}| jr,|dO }| jr:|dO }|| || j || j d S )Nr[   r\   )rA   r^   rY   r9   r   rI   r   r   r_   r#   r#   r$   rb      s    
zContextualMorphAction.compilec                 C   s\   |d kst | | _| }t|d@ | _t|d@ | _|d@ | _| | _| | _d S )Nr[   r\   i?  )	rA   rc   rY   rd   r   rI   r9   r   r   re   r#   r#   r$   rh      s    


zContextualMorphAction.decompilec                 C   s~   |j |f| |  |jd| jd |  | | |jd| jd |  |jd| jd |  || |  d S )NrY   r7   r   r   )ri   r=   r;   rY   r@   r   r   rm   r"   r>   r-   rn   ro   r#   r#   r$   rp      s    

zContextualMorphAction.toXMLc           	      C   s   d | _ | _d | _| _d\| _| _dd |D }|D ]\}}}|dkrXt|d | _ q6|dkr|d d	D ]}| |	  qnq6|d
krt|d | _q6|dkrt|d | _q6|dkr6t|d | _q6d S )Nr   Fr   c                 S   s   g | ]}t |tr|qS r#   rq   rt   r#   r#   r$   r4      s     
 z1ContextualMorphAction.fromXML.<locals>.<listcomp>rY   r8   r5   r6   r9   r   r   )
rY   r9   r   rI   r   r   r   rv   rD   rw   rx   r#   r#   r$   r}      s     zContextualMorphAction.fromXMLN)r'   r(   r)   r~   r   r:   r%   rb   rh   rp   r}   r#   r#   r#   r$   r      s   
r   c                   @   s   e Zd Zdd ZdS )	LigActionc                 C   s   d| _ d| _d S )NFr   )StoreGlyphIndexDeltar!   r#   r#   r$   r%      s    
zLigAction.__init__Nr&   r#   r#   r#   r$   r      s   r   c                   @   s`   e Zd ZdZdZddgZdd Zdd Zd	d
 Ze	dd Z
dd Zdd Zdd Zdd ZdS )LigatureMorphActionrN   rT   SetComponentrI   c                 C   s"   d| _ d\| _| _d| _g | _d S )Nr   r   )rY   r   rI   r9   Actionsr!   r#   r#   r$   r%      s    zLigatureMorphAction.__init__c                 C   s   |d k	st || j | j}| jr,|dO }| jr:|dO }t| jdkrP|dO }|| t| jdkr|  }|||  n
|d d S )Nr[   r\   r   r]   )	rA   r^   rY   r9   r   rI   lenr   compileLigActions)r"   r`   r-   ra   r?   actionsr#   r#   r$   rb      s    
zLigatureMorphAction.compilec                 C   sv   |d k	st | | _| }t|d@ | _t|d@ | _t|d@ }|d@ | _| }|rl| ||| _ng | _d S )Nr[   r\   r]   i  )	rA   rc   rY   rd   r   rI   r9   _decompileLigActionsr   )r"   rf   r-   rg   r?   ZperformActionra   r#   r#   r$   rh     s    

zLigatureMorphAction.decompilec                 C   s   dt  i   }}}|D ]&}|j D ]\}}||  q$qt|dd dD ]R}||krNtdt|dD ],}	||	d  }
t||	 d }||
| qj||7 }qNt	|d}||fS )N    c                 S   s   t |  | fS r    r   xr#   r#   r$   <lambda>1  r   z4LigatureMorphAction.compileActions.<locals>.<lambda>keyr   rG   )
setr+   itemsaddr   sortedranger   
setdefaultr   )r-   r.   resultr   ra   state_glyphClasstransaisuffixZsuffixIndexr#   r#   r$   r/      s    

z"LigatureMorphAction.compileActionsc                 C   sp   g }t | jD ]X\}}|t| jd k}|jd@ }||r<dndO }||jrNdndO }|td| qt|S )Nr   ?        r      @z>L)		enumerater   r   r   r   appendstructpackr   )r"   r   r   actionlastr8   r#   r#   r$   r   ;  s    
z%LigatureMorphAction.compileLigActionsc           	      C   sv   g }d}| |j|d  }|sr| }t|d@ }t }|| t|d@ |_|d@ }|dkrjd| }||_q|S )NFrG   r   r   r   i    i   )getSubReaderposZ	readULongrd   r   r   r   r   )	r"   rg   ra   r   r   rf   r8   r   deltar#   r#   r$   r   E  s    
z(LigatureMorphAction._decompileLigActionsc                 C   s   d | _ | _d | _| _d| _g | _dd |D }|D ]\}}}|dkrXt|d | _ q6|dkr|d dD ]}| |  qnq6|d	krt|d | _q6|d
kr6t	 }	|
ddd}
dd |
D }
d|
k|	_t|d |	_| j|	 q6d S )Nr   Fc                 S   s   g | ]}t |tr|qS r#   rq   rt   r#   r#   r$   r4   Z  s     
 z/LigatureMorphAction.fromXML.<locals>.<listcomp>rY   r8   r5   r6   r9   Action c                 S   s   g | ]}|  qS r#   rw   r1   r#   r#   r$   r4   f  s     r   r   )rY   r9   r   rI   r   r   rv   rD   rw   r   rk   r   r   r   )r"   ro   rn   ry   r-   rz   r{   r|   rC   r   r?   r#   r#   r$   r}   U  s(    
zLigatureMorphAction.fromXMLc                 C   s   |j |f| |  |jd| jd |  | | | jD ]4}d|jfg}|jr^|d |d| |  q>|	| |  d S )NrY   r7   r   )r5   r   r   )
ri   r=   r;   rY   r@   r   r   r   r   rm   )r"   r>   r-   rn   ro   r   Zattribsr#   r#   r$   rp   k  s    




zLigatureMorphAction.toXMLN)r'   r(   r)   r~   r   r:   r%   rb   rh   rE   r/   r   r   r}   rp   r#   r#   r#   r$   r      s   

r   c                   @   s`   e Zd ZdZdZddddddgZd	d
 Zdd Zdd Zdd Z	dd Z
dd Zedd ZdS )InsertionMorphActionrP   rG   r   rI   CurrentIsKashidaLikeMarkedIsKashidaLikeCurrentInsertBeforeMarkedInsertBeforec                 C   s6   d| _ | jD ]}t| |d qd| _g g  | _| _d S rX   )rY   r:   setattrr9   CurrentInsertionActionMarkedInsertionActionrB   r#   r#   r$   r%     s
    
zInsertionMorphAction.__init__c                 C   s   |d k	st || j | j}| jr,|dO }| jr:|dO }| jrH|dO }| jrV|dO }| jrd|dO }| j	rr|dO }|t
| jd> O }|t
| jO }|| t
| jdkr|t| j }nd	}|| t
| jdkr|t| j }nd	}|| d S )
Nr[   r\   r]            rM   r   r   )rA   r^   rY   r9   r   rI   r   r   r   r   r   r   r   rs   )r"   r`   r-   ra   r?   ZcurrentIndexZmarkedIndexr#   r#   r$   rb     s4    

zInsertionMorphAction.compilec                 C   s   |d k	st | | _| }t|d@ | _t|d@ | _t|d@ | _t|d@ | _t|d@ | _t|d@ | _	| j
||| |d@ d? d	| _| j
||| |d
@ d	| _d S )Nr[   r\   r]   r   r   r   i  rM   )indexcount   )rA   rc   rY   rd   r   rI   r   r   r   r   _decompileInsertionActionr   r   re   r#   r#   r$   rh     s*    
   
   zInsertionMorphAction.decompilec                 C   s8   |dks|dkrg S | |j|d  }|||S )Nr   r   rK   )r   r   getGlyphNameManyZreadUShortArray)r"   rg   r-   r   r   rf   r#   r#   r$   r     s    z.InsertionMorphAction._decompileInsertionActionc                 C   s   |j |f| |  |jd| jd |  | | | jD ]}|jd|d |  q>| jD ]}|jd|d |  q`|| |  d S )NrY   r7   r   glyphr   )ri   r=   r;   rY   r@   r   r   rm   )r"   r>   r-   rn   ro   gr#   r#   r$   rp     s    





zInsertionMorphAction.toXMLc           	      C   s   |    dd |D }|D ]\}}}|dkr<t|d | _q|dkrh|d dD ]}| |  qRq|dkr| j|d  q|d	kr| j|d  qd
st	|qd S )Nc                 S   s   g | ]}t |tr|qS r#   rq   rt   r#   r#   r$   r4     s     
 z0InsertionMorphAction.fromXML.<locals>.<listcomp>rY   r8   r5   r6   r   r   r   F)
r%   r   rY   rv   rD   rw   r   r   r   rA   rx   r#   r#   r$   r}     s    zInsertionMorphAction.fromXMLc                 C   s  t  i d  }}}|D ]L}|j D ]<\}}|jd k	rF|t|j |jd k	r$|t|j q$qt|dd dD ]}||krqttdt	|D ]D}	t	|d |	 }
t|	t	|D ] }||	|d  }|
||
 qq|D ]}| |}|td|7 }qqt||fS )	Nr   c                 S   s   t |  | fS r    r   r   r#   r#   r$   r     r   z5InsertionMorphAction.compileActions.<locals>.<lambda>r   r   rK   r   z>H)r   r+   r   r   r   rs   r   r   r   r   r   
getGlyphIDr   r   )r-   r.   r   ra   r   r   r   r   r   startZ
startIndexlimitglyphsr   glyphIDr#   r#   r$   r/     s&    


z#InsertionMorphAction.compileActionsN)r'   r(   r)   r~   r   r:   r%   rb   rh   r   rp   r}   rE   r/   r#   r#   r#   r$   r   {  s"   	r   c                   @   s   e Zd Zdd ZdddZdS )FeatureParamsc                 C   s>   t |d | jks,td|d | jjf t| || d S )NZ
FeatureTagz-Wrong FeatureParams type for feature '%s': %s)featureParamTypesrk   	__class__rA   r'   r   rb   )r"   r`   r-   r#   r#   r$   rb     s    zFeatureParams.compileNc                 C   s   t j| |||| jjd d S )N)ro   )r   rp   r   r'   r   r#   r#   r$   rp     s    zFeatureParams.toXML)NN)r'   r(   r)   rb   rp   r#   r#   r#   r$   r     s   	r   c                   @   s   e Zd ZdS )FeatureParamsSizeNr'   r(   r)   r#   r#   r#   r$   r     s   r   c                   @   s   e Zd ZdS )FeatureParamsStylisticSetNr   r#   r#   r#   r$   r     s   r   c                   @   s   e Zd ZdS )FeatureParamsCharacterVariantsNr   r#   r#   r#   r$   r     s   r   c                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )CoverageNc                 C   s   t | dsg | _d S )Nr   )hasattrr   r"   Z
propagatorr#   r#   r$   populateDefaults   s    
zCoverage.populateDefaultsc                 C   s   | j dkr|d | _n| j dkrg  }| _|d }t|dd d}||krXtd |}~|D ]>}|j}|j}||}	||d }
||	t
|	|
 q^ng | _td	| j  | ` d S )
Nr   
GlyphArrayrK   RangeRecordc                 S   s   | j S r    )StartCoverageIndexr   r#   r#   r$   r   -  r   z#Coverage.postRead.<locals>.<lambda>r   .GSUB/GPOS Coverage is not sorted by glyph ids.zUnknown Coverage format: %s)Formatr   r   logwarningStartEndr   extendr   r   )r"   rawTabler-   r   rangesZsorted_rangesrr   endstartIDendIDr#   r#   r$   postRead$  s&    




zCoverage.postReadc                 C   sd  t | dd }|d krg  }| _d}d|i}|rZ||}t||k}|d }|gg}|dd  D ].}	|	|d kr|d | ||	g |	}qb|d | |st|d t|k rZd}
tt|D ]R}|| \}}t }||_|	||_
|	||_|
|_|||< |
| | d }
q|r>td |jdd	 d
 |D ]
}|`qBd}d|i}|| _|S )Nr   r   r   r   rL   r   c                 S   s   | j S r    )StartIDr   r#   r#   r$   r   _  r   z#Coverage.preWrite.<locals>.<lambda>r   rK   r   )getattrr   getGlyphIDManyr   r   r   r   r   r   ZgetGlyphNamer   r   r   r   r   sortr   )r"   r-   r   formatr   glyphIDsZbrokenOrderr   r   r   r   r   r   r   r   r#   r#   r$   preWrite=  sH    


zCoverage.preWritec                 C   s,   t | dg D ]}|jd|d |  qd S )Nr   Glyphr7   )r   r;   r=   )r"   r>   r-   	glyphNamer#   r#   r$   toXML2i  s    zCoverage.toXML2c                 C   s0   t | dd }|d krg }|| _||d  d S )Nr   r8   )r   r   r   )r"   ro   rn   ry   r-   r   r#   r#   r$   r}   n  s
    zCoverage.fromXML)Nr'   r(   r)   r   r   r   r   r}   r#   r#   r#   r$   r     s
   
,r   l    c                   @   sB   e Zd ZdddZdd Zedd Zdd	 Zd
d Zdd Z	dS )DeltaSetIndexMapNc                 C   s   t | dsg | _d S Nmappingr   r   r   r#   r#   r$   r   |  s    
z!DeltaSetIndexMap.populateDefaultsc                 C   s"   |d d@ dkst |d | _d S )NEntryFormat  r   r   )rA   r   )r"   r   r-   r#   r#   r$   r     s    zDeltaSetIndexMap.postReadc                 C   s   d}| D ]}||O }q|d@ }d}|r8|d7 }|dL }q"t |d}|dksNt|d| ? |d|> d @ B }|dkrxd}n |dkrd}n|dkrd}nd	}|d d	> |d B S )
Nr   r   r         rK   i rL   rG   )maxrA   )r   ZoredidxinnerZ	innerBitsZ	entrySizer#   r#   r$   getEntryFormat  s&    


zDeltaSetIndexMap.getEntryFormatc                 C   s\   t | dd }|d krg  }| _t|dkr.dnd| _| j }t||d< | ||d< |S )Nr   r   r   r   MappingCountr   )r   r   r   r   r0   copyr  )r"   r-   r   r   r#   r#   r$   r     s    

zDeltaSetIndexMap.preWritec                 C   st   | d |  tt| dg D ]L\}}d|fg}|tkrZ|d|d? fd|d@ fg |d| |  q"d S )	Nz7Omitted values default to 0xFFFF/0xFFFF (no variations)r   r   outerr   r   r   Map)rl   r=   r   r   NO_VARIATION_INDEXr   r;   )r"   r>   r-   r   r8   rn   r#   r#   r$   r     s    



zDeltaSetIndexMap.toXML2c           	      C   sn   t | dd }|d krg  | _}t|d }t|dd}t|dd}|dksVt|||d> |B  d S )Nr   r   r  Z0xFFFFr   r   r   )r   r   r   rk   rA   insert)	r"   ro   rn   ry   r-   r   r   r  r   r#   r#   r$   r}     s    
zDeltaSetIndexMap.fromXML)N)
r'   r(   r)   r   r   rE   r  r   r   r}   r#   r#   r#   r$   r   {  s   


r   Zuint8c                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )	VarIdxMapNc                 C   s   t | dsi | _d S r   r   r   r#   r#   r$   r     s    
zVarIdxMap.populateDefaultsc                 C   sX   |d d@ dkst | }|d }||d gt|t|   tt||| _d S )Nr   r   r   r   r   )rA   getGlyphOrderr   r   dictzipr   )r"   r   r-   
glyphOrderZmapListr#   r#   r$   r     s
     zVarIdxMap.postReadc                    s   t | dd   d kri   | _| } fdd|D  t dkr\ d  d kr\ d= q8d i}t |d< t |d< |S )	Nr   c                    s   g | ]} | qS r#   r#   r2   r   r   r#   r$   r4     s     z&VarIdxMap.preWrite.<locals>.<listcomp>r   r   r  r   )r   r   r	  r   r   r  )r"   r-   r  r   r#   r  r$   r     s    
zVarIdxMap.preWritec                 C   sT   t t| di  D ]:\}}d|fd|d? fd|d@ ff}|d| |  qd S )Nr   r   r  r   r   r   r  )r   r   r   r;   r=   )r"   r>   r-   r   r8   rn   r#   r#   r$   r     s    

zVarIdxMap.toXML2c           	      C   s   t | dd }|d kri }|| _z|d }W n   | |d  }Y nX t|d }t|d }|dkslt|d> |B ||< d S )Nr   r   r   r  r   r   r   )r   r   r	  r   rA   )	r"   ro   rn   ry   r-   r   r   r  r   r#   r#   r$   r}     s    zVarIdxMap.fromXML)Nr   r#   r#   r#   r$   r    s
   

r  c                   @   s   e Zd Zdd ZdS )VarRegionListc                 C   s0   | d}|rt|j| _| jdt| jdiS )NZfvarRegionAxisCount)rk   r   Zaxesr  r0   r   )r"   r-   Z	fvarTabler#   r#   r$   r     s    
 
zVarRegionList.preWriteNr'   r(   r)   r   r#   r#   r#   r$   r    s   r  c                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )SingleSubstNc                 C   s   t | dsi | _d S r   r   r   r#   r#   r$   r     s    
zSingleSubst.populateDefaultsc                    s   i }t |d }| jdkrf|d  ||} fdd|D }||}t||D ]\}}	|	||< qRnZ| jdkrt||d kstd|d	 }
t||
D ]\}}|||< qnd
std| j || _| `d S )Nr   r   DeltaGlyphIDc                    s   g | ]}|  d  qS )   r#   )r2   r   r   r#   r$   r4     s     z(SingleSubst.postRead.<locals>.<listcomp>rK   Z
GlyphCountz invalid SingleSubstFormat2 table
Substituter   unknown format: %s)_getGlyphsFromCoverageTabler   r   r   r  r   rA   r   )r"   r   r-   r   inputZ	inputGIDSZoutGIDSZoutNamesinpoutsubstsubr#   r  r$   r     s(    



zSingleSubst.postReadc                    s  t | dd }|d kri  }| _t| }|j  fdd|D }tt||}d}d }|D ]0\}}	|d krx|	| d }|| d |	kr\ qq\|d krd}nd}i }
|| _t }dd |D }dd |D }||_	||
d	< |dkr|d k	st
||
d
< n||
d< |
S )Nr   c                    s    g | ]\}} | |fqS r#   r#   )r2   r   br   r#   r$   r4   +  s     z(SingleSubst.preWrite.<locals>.<listcomp>rK   r  r   c                 S   s   g | ]}|d  d qS )r   r   r#   r2   itemr#   r#   r$   r4   A  s     c                 S   s   g | ]}|d  d  qS r   r#   r!  r#   r#   r$   r4   B  s     r   r  r  )r   r   listr   r   r   r  r   r   r   rA   )r"   r-   r   r   ZgidItemsZsortableItemsr   r   ZinIDZoutIDr   covr  r  r#   r   r$   r   %  s:    

zSingleSubst.preWritec                 C   s@   t | j }|D ](\}}|dd|fd|fg |  qd S )NSubstitutioninr  )r   r   r   r;   r=   )r"   r>   r-   r   inGlyphZoutGlyphr#   r#   r$   r   L  s    zSingleSubst.toXML2c                 C   s2   t | dd }|d kri }|| _|d ||d < d S )Nr   r  r'  )r   r   )r"   ro   rn   ry   r-   r   r#   r#   r$   r}   R  s
    zSingleSubst.fromXML)Nr   r#   r#   r#   r$   r  
  s
   
'r  c                   @   sB   e Zd ZdddZdd Zdd Zdd	 Zd
d Zedd Z	dS )MultipleSubstNc                 C   s   t | dsi | _d S r   r   r   r#   r#   r$   r   [  s    
zMultipleSubst.populateDefaultsc                 C   s\   i }| j dkr<t|d }dd |d D }tt||}ndsNtd| j  || _| ` d S )Nr   r   c                 S   s   g | ]
}|j qS r#   )r  )r2   sr#   r#   r$   r4   c  s     z*MultipleSubst.postRead.<locals>.<listcomp>Sequencer   r  )r   r  r
  r  rA   r   )r"   r   r-   r   r   r  r#   r#   r$   r   _  s    
zMultipleSubst.postReadc                    sb   t dd   d kri   _t }tt  |jd|_d_| fdd|jD d}|S )Nr   r   r   c                    s   g | ]}  | qS r#   )makeSequence_)r2   r   r   r"   r#   r$   r4   s  s     z*MultipleSubst.preWrite.<locals>.<listcomp>)r   r+  )	r   r   r   r   r$  keysr   r   r   )r"   r-   r%  r   r#   r-  r$   r   j  s    
zMultipleSubst.preWritec                 C   sJ   t | j }|D ]2\}}d|}|dd|fd|fg |  qd S )Nr6   r&  r'  r  )r   r   r   r<   r;   r=   )r"   r>   r-   r   r(  	outGlyphsr  r#   r#   r$   r   w  s
    
zMultipleSubst.toXML2c                 C   s  t | dd }|d kri }|| _|dkrhg | _|D ]2}t|ts@q0|\}}}	|dkr0| j|d  q0d S |dkrt|dt|}
| j|
 }g  }||< |D ]0}t|tsq|\}}}	|dkr||d  qd S |d r|d 	d	ng }d
d |D ||d < d S )Nr   r   r   r8   r+  r   r  r  r6   c                 S   s   g | ]}|  qS r#   r   r  r#   r#   r$   r4     s     z)MultipleSubst.fromXML.<locals>.<listcomp>r'  )
r   r   Zold_coverage_rr   rs   r   intrk   r   rv   )r"   ro   rn   ry   r-   r   elementZelement_nameZelement_attrs_r   r   Zglyph_mappingr/  r#   r#   r$   r}   ~  s4    




zMultipleSubst.fromXMLc                 C   s   t  }| |_|S r    )r+  r  )r   seqr#   r#   r$   r,    s    zMultipleSubst.makeSequence_)N)
r'   r(   r)   r   r   r   r   r}   rE   r,  r#   r#   r#   r$   r)  Z  s   
 r)  c                   @   s>   e Zd ZdddZdd Zdd Zdd	 Zd
d Zdd ZdS )ClassDefNc                 C   s   t | dsi | _d S )N	classDefs)r   r5  r   r#   r#   r$   r     s    
zClassDef.populateDefaultsc                 C   s   i }| j dkrf|d }|d }||}|t| }|t||}t||D ]\}	}
|
rN|
||	< qNn~| j dkr|d }|D ]V}|j}
|
sq||j}|j}||}||d }|t||}|D ]}	|
||	< qq|nt	
d| j  || _| ` d S )Nr   
StartGlyphClassValueArrayrK   ClassRangeRecordzUnknown ClassDef format: %s)r   r   r   r   r   r  Classr   r   r   r   r5  )r"   r   r-   r5  r   Z	classListr   r   Z
glyphNamesr   clsrecordsrecr   r#   r#   r$   r     s4    



zClassDef.postReadc                 C   s   t | dd }|d kri | _d S |j}g }| D ]"\}}|s>q0|||||f q0|r|  |d \}}}	|	||gg}
|dd  D ]L\}}}||d ks||	kr|
d ||g |
|||g |}|}|}	q|
d ||g |
S d S )Nr5  r   r   r   )r   r5  r   r   r   r   r   )r"   r-   r5  r   r   r   r:  r   ZlastNameZlastClsr   r   r#   r#   r$   _getClassRanges  s.    zClassDef._getClassRangesc                 C   s  d}dg i}|  |}|r|d d }|d d }|| d }t|d |d k rtt|D ]6}|| \}	}
}}}t }||_||_|	|_|||< q`d}d|i}n\|d d }dg| }|D ]2\}	}
}}}t|
| || d D ]}|	||< qqd}||d}|| _|S )NrK   r8  r   r   r   rL   )r6  r7  )r=  r   r   r8  r   r   r9  r   )r"   r-   r   r   r   Z
startGlyphZendGlyphZ
glyphCountr   r:  r   	startNamer   endNamer<  ZstartGlyphNameclassesr   r#   r#   r$   r     s4    




zClassDef.preWritec                 C   s@   t | j }|D ](\}}|dd|fd|fg |  qd S )Nr4  r   class)r   r5  r   r;   r=   )r"   r>   r-   r   r   r:  r#   r#   r$   r     s    zClassDef.toXML2c                 C   s6   t | dd }|d kri }|| _t|d ||d < d S )Nr5  rA  r   )r   r5  r0  )r"   ro   rn   ry   r-   r5  r#   r#   r$   r}     s
    zClassDef.fromXML)N)	r'   r(   r)   r   r   r=  r   r   r}   r#   r#   r#   r$   r4    s   
r4  c                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )AlternateSubstNc                 C   s   t | dsi | _d S )N
alternates)r   rC  r   r#   r#   r$   r     s    
zAlternateSubst.populateDefaultsc                 C   sv   i }| j dkrVt|d }|d }t|t|ks6tt||D ]\}}|j||< q@ndshtd| j  || _| ` d S )Nr   r   AlternateSetr   r  )r   r  r   rA   r  	AlternaterC  )r"   r   r-   rC  r  altsr  altr#   r#   r$   r     s    
zAlternateSubst.postReadc           
      C   s   d| _ t| dd }|d kr$i  }| _t| }tt|D ]$}|| \}}||||f||< q<|  t	 }dd |D |_
g }dd |D }|D ]}t }	||	_||	 qd| _||dS )Nr   rC  c                 S   s   g | ]}|d  qS r#  r#   r!  r#   r#   r$   r4   ,  s     z+AlternateSubst.preWrite.<locals>.<listcomp>c                 S   s   g | ]}|d  qS r   r#   r!  r#   r#   r$   r4   .  s     )r   rD  )r   r   rC  r$  r   r   r   r   r   r   r   rD  rE  r   sortCoverageLast)
r"   r-   rC  r   r   r   r   r%  setListrF  r#   r#   r$   r   !  s&    
zAlternateSubst.preWritec                 C   sh   t | j }|D ]P\}}|jd|d |  |D ]}|jd|d |  q4|d |  qd S )NrD  r   rE  )r   rC  r   ri   r=   r;   rm   )r"   r>   r-   r   r   rC  rG  r#   r#   r$   r   ;  s    

zAlternateSubst.toXML2c           	      C   sd   t | dd }|d kri }|| _|d }g }|||< |D ](}t|tsFq6|\}}}||d  q6d S )NrC  r   )r   rC  rr   rs   r   )	r"   ro   rn   ry   r-   rC  r   r   r1  r#   r#   r$   r}   F  s    

zAlternateSubst.fromXML)Nr   r#   r#   r#   r$   rB    s
   
rB  c                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )LigatureSubstNc                 C   s   t | dsi | _d S )N	ligatures)r   rL  r   r#   r#   r$   r   V  s    
zLigatureSubst.populateDefaultsc                 C   s|   i }| j dkr\t|d }|d }t|t|ks6ttt|D ]}|| j||| < qBndsntd| j  || _| ` d S )Nr   r   LigatureSetr   r  )r   r  r   rA   r   LigaturerL  )r"   r   r-   rL  r  ligSetsr   r#   r#   r$   r   Z  s    
zLigatureSubst.postReadc                 C   sV  d| _ t| dd }|d kr$i  }| _|rttt|trt }t|	 dd dD ]B\}}t
 }|dd  |_t||_||_||d g | qT|}t|	 }tt|D ]$}|| \}	}
||	|	|
f||< q|  t }dd |D |_g }d	d |D }|D ]6}
t }g  }|_
|
D ]}|| q&|| qd| _||d
S )Nr   rL  c                 S   s   t | d  | d fS Nr   r   r"  r#   r#   r$   r   t  r   z(LigatureSubst.preWrite.<locals>.<lambda>r   r   c                 S   s   g | ]}|d  qS r#  r#   r!  r#   r#   r$   r4     s     z*LigatureSubst.preWrite.<locals>.<listcomp>c                 S   s   g | ]}|d  qS rH  r#   r!  r#   r#   r$   r4     s     )r   rM  )r   r   rL  rr   nextiterrs   r
  r   r   rN  	Componentr   	CompCountLigGlyphr   r   r$  r   r   r   r   r   rM  rI  )r"   r-   rL  ZnewLigaturescompsligZligaturer   r   r   r   r%  rO  rJ  ZligSetligsr#   r#   r$   r   g  sB    
 

zLigatureSubst.preWritec                 C   st   t | j }|D ]\\}}|jd|d |  |D ]&}|jd|jd|jd |  q4|	d |  qd S )NrM  r   rN  r6   )r   
components)
r   rL  r   ri   r=   r;   rV  r<   rT  rm   )r"   r>   r-   r   r   rO  rX  r#   r#   r$   r     s      


zLigatureSubst.toXML2c                 C   s   t | dd }|d kri }|| _|d }g }|||< |D ]\}t|tsFq6|\}}}t }	|d |	_|d }
|
rv|
dng |	_t|	j|	_	|
|	 q6d S )NrL  r   rZ  r6   )r   rL  rr   rs   rN  rV  rv   rT  r   rU  r   )r"   ro   rn   ry   r-   rL  r   rY  r1  rX  rZ  r#   r#   r$   r}     s"    


zLigatureSubst.fromXML)Nr   r#   r#   r#   r$   rK  U  s
   
,rK  c                   @   s.   e Zd Zdd Zdd Zddeddd	Zd
S )COLRc                 C   sb   |j dd}|  D ]6}|jdkr0||j q|j||i d||j<  qTqtdt| ||S )Nr   )offsetLayerRecordCount)Z	tableDictz$LayerRecordCount converter not found)	r   getConvertersro   Zadvancer~   readrA   r   rh   )r"   rf   r-   Z	subReaderconvr#   r#   r$   rh     s    
zCOLR.decompilec                 C   s   d | _ | jdt| jdiS )Nr]  )r]  r0   r   r"   r-   r#   r#   r$   r     s
     
zCOLR.preWriter   r   )glyphSetquantizationc           	      C   s   | j dkrd S i }| jjD ]l}z|j| ||}W n@ tk
rr } z"ddlm} |d|j|W 5 d }~X Y nX |d k	r|||j< qt	| do| j
d k	}|s|rd | _
n|st
 | _
d| j
_|| j
_d S )Nr   )
TTLibErrorz#Failed to compute COLR ClipBox for ClipListr   )VersionBaseGlyphListBaseGlyphPaintRecordPaintcomputeClipBox	ExceptionZfontTools.ttLibrd  	BaseGlyphr   re  r   clips)	r"   rb  rc  rm  r<  clipBoxerd  ZhasClipListr#   r#   r$   computeClipBoxes  s.    

zCOLR.computeClipBoxesN)r   )r'   r(   r)   rh   r   r0  rp  r#   r#   r#   r$   r[    s   
r[  c                       s(   e Zd Zedd Z fddZ  ZS )
LookupListc                 C   sP   | j D ]@}|jD ]4}t|jdr,  dS t|jdr  dS qqtd S )NZSubstGSUBZPosGPOS)LookupSubTabletyper'   endswith
ValueError)r"   lstr#   r#   r$   table  s    

zLookupList.tablec              
      sL  |rd|kst |d jkr(t ||S |d jt  | j }|  D ] }|jrt| |jg }t	|D ]\}}t
||krt|t
|  }|j}	|jr|j d|	 }	|jr|j\}
}}|	 d| d|
 d| d}	||	 |  |||||jd|fg qhqD|jr$t|jd t| s$qDt| |jd }|||||jg  qDd S )NZDebgz: z in z (/)r   )r   datasuperr   r{  r^  repeatr   ro   r   strr   locationfeaturerl   r=   ZxmlWriteZauxevalvars)r"   r>   r-   Z	debugDatar`  r8   lookupIndexr"  infotagscriptlanguager  r   r#   r$   r     sJ    
      zLookupList.toXML2)r'   r(   r)   propertyr{  r   __classcell__r#   r#   r  r$   rq    s   
	rq  c                   @   s   e Zd Zdd ZdS )BaseGlyphRecordArrayc                    s"   t | j fddd| _| j S )Nc                    s     | jS r    r   rl  r<  r-   r#   r$   r     r   z/BaseGlyphRecordArray.preWrite.<locals>.<lambda>r   )r   ZBaseGlyphRecordr0   r  ra  r#   r  r$   r     s
     
zBaseGlyphRecordArray.preWriteNr  r#   r#   r#   r$   r    s   r  c                   @   s   e Zd Zdd ZdS )rg  c                    s"   t | j fddd| _| j S )Nc                    s     | jS r    r  r  r  r#   r$   r   &  r   z(BaseGlyphList.preWrite.<locals>.<lambda>r   )r   rh  r0   r  ra  r#   r  r$   r   $  s
     
zBaseGlyphList.preWriteNr  r#   r#   r#   r$   rg  #  s   rg  c                   @   s$   e Zd ZdZdZdd Zdd ZdS )ClipBoxFormatr   rK   c                 C   s
   | | j kS r    Variabler!   r#   r#   r$   is_variable/  s    zClipBoxFormat.is_variablec                 C   s   | j S r    r  r!   r#   r#   r$   as_variable2  s    zClipBoxFormat.as_variableN)r'   r(   r)   Staticr  r  r  r#   r#   r#   r$   r  +  s   r  c                   @   s    e Zd ZeZdd Zdd ZdS )ClipBoxc                    s   t  fdd  D S )Nc                 3   s   | ]}t  |jV  qd S r    )r   ro   )r2   r`  r!   r#   r$   	<genexpr>:  s     z#ClipBox.as_tuple.<locals>.<genexpr>)rs   r^  r!   r#   r!   r$   as_tuple9  s    zClipBox.as_tuplec                 C   s   | j j |   S r    )r   r'   r  r!   r#   r#   r$   __repr__<  s    zClipBox.__repr__N)r'   r(   r)   r  
formatEnumr  r  r#   r#   r#   r$   r  6  s   r  c                   @   s@   e Zd ZdddZdd Zdd Zdd	 Zdd
dZdd ZdS )re  Nc                 C   s   t | dsi | _d S )Nrm  )r   rm  r   r#   r#   r$   r   A  s    
zClipList.populateDefaultsc              
   C   s   i }|  }t|d D ]\}}|j|jkrBtd||j|j qg }g }t|j|jd D ]X}	z||	 }
W n" tk
r   ||	 Y q\Y nX |
|krt		|j
||
< q\||	 q\|rtd|t|t| |rtd|t|t| q|| _d S )N
ClipRecordzCinvalid ClipRecord[%i].StartGlyphID (%i) > EndGlyphID (%i); skippedr   zqClipRecord[%i] overlaps previous records; ignoring redefined clip boxes for the following glyph ID range: [%i-%i]z:ClipRecord[%i] range references missing glyph IDs: [%i-%i])r	  r   StartGlyphID
EndGlyphIDr   r   r   
IndexErrorr   r  r  minr   rm  )r"   r   r-   rm  r  r   r<  ZredefinedGlyphsZmissingGlyphsr   r   r#   r#   r$   r   E  sJ    

zClipList.postReadc                    s\   t t}i  | j D ].\}}| }|| | | kr| |< q fdd| D S )Nc                    s   i | ]\}}t | | qS r#   )	frozenset)r2   r   r   ZuniqueClipsr#   r$   
<dictcomp>x  s     z#ClipList.groups.<locals>.<dictcomp>)r   r$  rm  r   r  r   )r"   ZglyphsByClipr   rn  r   r#   r  r$   groupsp  s    

zClipList.groupsc                    s$  t | dsi | _i }|  |   D ]\}}t fdd|D }|sLq(|d }|gg}|dd  D ].}||d kr|d | ||g |}qh|d | |D ]$\}	}
|	|
f|kst|||	|
f< qq(g }t| D ].\\}	}
}t }|	|_	|
|_
||_|| qt||d}|S )Nrm  c                 3   s   | ]}| kr | V  qd S r    r#   )r2   r   ZglyphMapr#   r$   r    s     z$ClipList.preWrite.<locals>.<genexpr>r   r   r   )Z	ClipCountr  )r   rm  ZgetReverseGlyphMapr  r   r   r   rA   r  r  r  r  r   )r"   r-   ZclipBoxRangesr   rn  r   r   r   r   r   r   ZclipRecordsrecordr   r#   r  r$   r   |  s@    
zClipList.preWritec           	      C   s  |r|n| j j}|d krg }t| dr6|d| jf ||| |  t|  	 dd dD ]\}}|d |  t|D ]}|j
d|d |  q|dd|jfg |  ||| |d |  |d |  qb|| |  d S )	Nr   c                 S   s   t | d S rP  )r  rQ  r#   r#   r$   r     r   z ClipList.toXML.<locals>.<lambda>r   Clipr   r7   r  )r   r'   r   r   r   ri   r=   r   r  r   r;   r   rm   )	r"   r>   r-   rn   ro   	tableNamer   rn  r   r#   r#   r$   rp     s2    

 





zClipList.toXMLc           
      C   s   t | dd }|d kri  | _}|dks*tg }d }|D ]~}t|tsFq6|\}}}|dkrh||d  q6|dkr6t }t|d |_|D ]*}t|tsq|\}}}|	|||| qq6|r|D ]}	|||	< qd S )Nrm  r  r   r8   r  r   )
r   rm  rA   rr   rs   r   r  r   r   r}   )
r"   ro   rn   ry   r-   rm  r   rn  elemr   r#   r#   r$   r}     s.    




zClipList.fromXML)N)NN)	r'   r(   r)   r   r   r  r   rp   r}   r#   r#   r#   r$   re  @  s   
+$
re  c                   @   s   e Zd ZdZdZdZdS )
ExtendModer   r   rK   N)r'   r(   r)   ZPADREPEATZREFLECTr#   r#   r#   r$   r    s   r  c                   @   s|   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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S )CompositeModer   r   rK   rL   rG   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   r                                    N)r'   r(   r)   ZCLEARZSRCZDESTZSRC_OVERZ	DEST_OVERZSRC_INZDEST_INZSRC_OUTZDEST_OUTZSRC_ATOPZ	DEST_ATOPZXORPLUSZSCREENZOVERLAYZDARKENZLIGHTENZCOLOR_DODGEZ
COLOR_BURNZ
HARD_LIGHTZ
SOFT_LIGHTZ
DIFFERENCEZ	EXCLUSIONZMULTIPLYZHSL_HUEZHSL_SATURATIONZ	HSL_COLORZHSL_LUMINOSITYr#   r#   r#   r$   r    s8   r  c                   @   s   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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!d Z"d!d" Z#d#d$ Z$d%S )&PaintFormatr   rK   rL   rG   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   r   r  r  r  r  r  r  r  r  r  r  r           r       c                 C   s   | j dS )NPaintVar)ro   
startswithr!   r#   r#   r$   r    s    zPaintFormat.is_variablec                 C   sD   |   r| S ztjd| jdd    W S  tk
r>   Y d S X d S )Nr  rM   )r  r  __members__ro   KeyErrorr!   r#   r#   r$   r  !  s    zPaintFormat.as_variableN)%r'   r(   r)   PaintColrLayersZ
PaintSolidZPaintVarSolidZPaintLinearGradientZPaintVarLinearGradientZPaintRadialGradientZPaintVarRadialGradientZPaintSweepGradientZPaintVarSweepGradient
PaintGlyphPaintColrGlyphPaintTransformZPaintVarTransformPaintTranslateZPaintVarTranslate
PaintScaleZPaintVarScalePaintScaleAroundCenterZPaintVarScaleAroundCenterPaintScaleUniformZPaintVarScaleUniformPaintScaleUniformAroundCenterZ PaintVarScaleUniformAroundCenterPaintRotateZPaintVarRotatePaintRotateAroundCenterZPaintVarRotateAroundCenter	PaintSkewZPaintVarSkewPaintSkewAroundCenterZPaintVarSkewAroundCenterZPaintCompositer  r  r#   r#   r#   r$   r    sD   r  c                   @   s   e Zd ZeZdd ZdddZeee	j
 dddZed  d	d
dZedddZed	ddZdedeee dddZdS )ri  c                 C   s:   z|  | jjW S  tk
r4   td| j Y nX d S )NzUnknown Paint format: )r  r   ro   rx  NotImplementedErrorr!   r#   r#   r$   getFormatName-  s    zPaint.getFormatNameNc                 C   sp   |r|n| j j}|d krg }|d| jf ||| ||   |  | || |	| |  d S )Nr   )
r   r'   r   r   ri   rl   r  r=   r   rm   )r"   r>   r-   rn   ro   r  r#   r#   r$   rp   3  s    
zPaint.toXML)colrreturnc                 c   s   | j tjkrPg }|jd k	r"|jj}dd t|| j| j| j  D E d H  d S | j tjkr|j	j
D ](}|j| jkrdtjd|jdV   d S qdt| jd|  D ]<}|jd k	rt|jt| rt| |j}tj|j|dV  qd S )Nc                 s   s"   | ]\}}t jd ||dV  qdS )ZLayers)ro   r8   r   N)r   SubTableEntry)r2   r   vr#   r#   r$   r  E  s   z+Paint.iterPaintSubTables.<locals>.<genexpr>rl  )ro   r8   z not in colr.BaseGlyphList)r   r  r  Z	LayerListri  r   ZFirstLayerIndexZ	NumLayersr  rg  rh  rl  r   r   r  r  r^  Z
tableClass
issubclassrv  r   ro   )r"   r  Zlayersr  r`  r8   r#   r#   r$   iterPaintSubTables?  s(    
zPaint.iterPaintSubTables)r  c                 C   s   dd |  |D S )Nc                 S   s   g | ]
}|j qS r#   r7   )r2   pr#   r#   r$   r4   \  s     z%Paint.getChildren.<locals>.<listcomp>r  )r"   r  r#   r#   r$   getChildrenZ  s    zPaint.getChildrenr  c                    s@   t |stdt|  fdddD ]}|d j}|| q$dS )zEDepth-first traversal of graph rooted at self, callback on each node.zcallback must be callablec                    s
   |   S r    r  paintr  r#   r$   r   d  r   z Paint.traverse.<locals>.<lambda>Ziter_subtables_fnr   N)callable	TypeErrorr   r8   )r"   r  callbackpathr  r#   r  r$   traverse^  s     


zPaint.traversec                 C   s  | j tjkr0| j}t|j|j|j|j|j|j	S | j tj
krLt| j| j	S | j tjkrht| j| jS | j tjkrt| j| j| j| j| j | j S | j tjkrt| jS | j tjk rt| j| j| j| j | j S | j tjkrtt| jS | j tjkrFt| j| jt| j| j | j S | j tjkrntt| j t| jS | j tjkrt| j| jt| j t| j| j | j S t| j   rt!d| j  tS )NzVariable Paints not supported: )"r   r  r  r
   ZxxZyxZxyyyZdxZdyr  r   	translater  ZscaleZscaleXZscaleYr  ZcenterXZcenterYr  r  r  rotater   Zangler  r  ZskewZ
xSkewAngleZ
ySkewAngler  r  r  )r"   ru   r#   r#   r$   getTransformi  sd        
  zPaint.getTransformr   r   )r  rb  rc  r  c           	         s   t |}t|  fdddD ]H}|d j}|jtjkrttjdd |D t	}||j
 t|| q|jd krtd S t }ttj|_t|j|\|_|_|_|_|S )Nc                    s
   |   S r    r  r  r  r#   r$   r     r   z&Paint.computeClipBox.<locals>.<lambda>r  r   c                 s   s   | ]}|j  V  qd S r    )r8   r  )r2   rz  r#   r#   r$   r    s     z'Paint.computeClipBox.<locals>.<genexpr>)r   r   r8   r   r  r  r   r
   Z	transformr   r   Zdrawr   Zboundsr  r0  r  r  r   ZxMinZyMinZxMaxZyMax)	r"   r  rb  rc  Zpenr  r  Ztransformationcbr#   r  r$   rj    s&     



zPaint.computeClipBox)NN)r   )r'   r(   r)   r  r  r  rp   r[  r   r   r  r  r   r  r  r
   r  r0  r   r  rj  r#   r#   r#   r$   ri  *  s   
,   ri  )Z
Mark1Array)ZDefaultLangSys)MarkCoverageBaseCoverageZLigatureCoverageZMark1CoverageZMark2CoverageZBacktrackCoverageZInputCoverageZLookAheadCoverageZVertGlyphCoverageZHorizGlyphCoverageZTopAccentCoverageZExtendedShapeCoverageZMathKernCoverage)	ClassDef1	ClassDef2ZBacktrackClassDefZInputClassDefZLookAheadClassDefZGlyphClassDefZMarkAttachClassDef)ZEntryAnchorZ
ExitAnchor
BaseAnchorZLigatureAnchorZMark2AnchorZ
MarkAnchor)Z
XPlaDeviceZ
YPlaDeviceZ
XAdvDeviceZ
YAdvDeviceZXDeviceTableZYDeviceTableZDeviceTable)Z	HorizAxisZVertAxis)ZDefaultMinMax)ZMinCoordZMaxCoord)ZDefJstfLangSys)ZShrinkageEnableGSUBZShrinkageDisableGSUBZExtensionEnableGSUBZExtensionDisableGSUB)ZShrinkageEnableGPOSZShrinkageDisableGPOSZExtensionEnableGPOSZExtensionDisableGPOS)ZShrinkageJstfMaxZExtensionJstfMax)ZTopRightMathKernZTopLeftMathKernZBottomRightMathKernZBottomLeftMathKern)ZVertGlyphConstructionZHorizGlyphConstruction)	MarkArrayZLangSysr   r4  ZAnchorZDeviceZAxisZMinMaxZ	BaseCoordZJstfLangSysZJstfGSUBModListZJstfGPOSModListZJstfMaxZMathKernZMathGlyphConstructionc                 C   s
  d}|j }|jdkr|d }|dk r(|S |jdkr8d}n|jdkrFd}| |j jjj}|| }|jd jj|kr|d }|dk r|S || }q^t	|t
|D ]d}|| }|j|kr||_t	t
|jD ]8}|j| }t|j | }	|	 }
d|
_||
_|
|j|< qqd}|S )a   Either the offset from the LookupList to a lookup overflowed, or
    an offset from a lookup to a subtable overflowed.
    The table layout is:
    GPSO/GUSB
            Script List
            Feature List
            LookUpList
                    Lookup[0] and contents
                            SubTable offset list
                                    SubTable[0] and contents
                                    ...
                                    SubTable[n] and contents
                    ...
                    Lookup[n] and contents
                            SubTable offset list
                                    SubTable[0] and contents
                                    ...
                                    SubTable[n] and contents
    If the offset to a lookup overflowed (SubTableIndex is None)
            we must promote the *previous*	lookup to an Extension type.
    If the offset from a lookup to subtable overflowed, then we must promote it
            to an Extension Lookup type.
    r   Nr   rr  rO   rs  rQ   )LookupListIndexSubTableIndex	tableTyper{  rq  rt  ru  r   
LookupTyper   r   lookupTypesr   ExtSubTable)ttfoverflowRecordokr  ZextTypeZlookupslookupsiZsubTableZextSubTableClassextSubTabler#   r#   r$   fixLookupOverFlows  s<    





r  c           
      C   s   d}t | j }t|}|jdkr.|d }n|jdkrB|jd }i |_t||D ]*}|| }|d }	|d |j|	< | j|	= qR|S )Nr   r   r   rK   r+  r   )r   r   r   r   itemName	itemIndexr   )
oldSubTablenewSubTabler  r  Z
oldMappingoldLennewLenr   r"  r   r#   r#   r$   splitMultipleSubstC  s    




r  c           
      C   s   d}t | dr| j|_t| j }t|}|jdkr@|d }n|jdkrT|jd }i |_t||D ]*}|| }|d }	|d |j|	< | j|	= qd|S )Nr   rI  r  rK   rD  r   )	r   rI  r   rC  r   r   r  r  r   )
r  r   r  r  ZoldAltsr  r  r   r"  r   r#   r#   r$   splitAlternateSubst]  s     





r  c           
      C   s   d}t | j }t|}|jdkr.|d }n|jdkrB|jd }i |_t||D ]*}|| }|d }	|d |j|	< | j|	= qR|S )Nr   r  rK   rM  r   )r   rL  r   r   r  r  r   )
r  r   r  r  ZoldLigsr  r  r   r"  r   r#   r#   r$   splitLigatureSubstz  s    




r  c           	         s  | }d}| j |_ | j dkrt| jdkrdD ]}t||t| | q,| j |_| jj}| j}t| jd |d  | j_|d  | _|d  |j_|d  |_t| j| _t|j|_d}nL| j dkrt| j	dkrt
| dst| j	d j| _dD ]}t||t| | qd| _| j |_| j |_| jj}| jj}| j	}t| j	d tfd	d
| D   fdd|D | j_fdd| D | j_|d  | _	 fdd|D |j_fdd| D |j_|d  |_	t| j	| _t|j	|_d}|S )NFr   )ValueFormat1ValueFormat2rK   TClass2Countr   )r  r  r  r  c                 3   s   | ]\}}| kr|V  qd S r    r#   r2   kr  oldCountr#   r$   r    s      zsplitPairPos.<locals>.<genexpr>c                    s   g | ]}| kr|qS r#   r#   r  	newGlyphsr#   r$   r4     s      z splitPairPos.<locals>.<listcomp>c                    s   i | ]\}}| k r||qS r#   r#   r	  r  r#   r$   r    s      z splitPairPos.<locals>.<dictcomp>c                    s   g | ]}| kr|qS r#   r#   r  r  r#   r$   r4     s      c                    s"   i | ]\}}| kr||  qS r#   r#   r	  r  r#   r$   r    s      )r   r   ZPairSetr   r   r   r   r   ZPairSetCountZClass1Recordr   ZClass2Recordr  	DontSharer  r5  r   r   ZClass1Count)	r  r   r  rz  r  ro   coverager;  r5  r#   )r  r  r$   splitPairPos  sX    



r  c                 C   s  | j }|dk rdS |d }|| }g g  }}g g  }}	t| jj| jjD ]J\}
}|j|k rp||
 || qH| j|8  _||
 |	| qHg g  }}| jj	D ]J}|
 |
  }}|jd | |_|j|d  |_|| || q| j|_|| j_| j
 |_||j_| j|_|| _ ||_ || j_| j
 |_|	|j_t|| j_t|	|j_|| j_	| j
 |_||j_	t|| j_t||j_dS )NrK   FT)Z
ClassCountr  r  r   r  Z
MarkRecordr9  r   Z	BaseArrayZ
BaseRecordr   r  r   r  r   Z	MarkCountZ	BaseCount)r  r   r  Z
classCountZoldClassCountZnewClassCountZoldMarkCoverageZoldMarkRecordsZnewMarkCoverageZnewMarkRecordsr   Z
markRecordZoldBaseRecordsZnewBaseRecordsr<  ZoldBaseRecordZnewBaseRecordr#   r#   r$   splitMarkBasePos  sT    

 




r  )rK   rL   rG   )rK   rG   rr  rs  c                 C   s6  | |j  j}|jj|j }|j}|j| }t|ds>d|_dS t|dr|j	j
j}|}|j	}t|j  |j
j }| }	|j|	_|	}
t|j  | }| }||	_	n |j
j}t|j  | }| }|}
t|dr|jd |_zt|j  | }W n( tk
r   td|j | Y dS X ||||}|r2|j|d |
 |S )zj
    An offset has overflowed within a sub-table. We need to divide this subtable into smaller parts.
    r  Tr  SubTableCountr   z)Don't know how to split %s lookup type %sF)r  r{  rq  rt  r  r  ru  r   r  r  r   r  r  r   r  
splitTabler  r   errorr  )r  r  r{  r  ZsubIndexZsubtableZsubTableTyper  ZnewExtSubTableClassZnewExtSubTableZtoInsertZnewSubTableClassr   Z	splitFuncr  r#   r#   r$   fixSubTableOverFlows0  sN    




r  c                  C   s|  dd l } ddlm} | d}t }|D ]d\}}t}||}|r`|d}|d d }t|}||kr(t||fi }	|dkrd|	_	|	||< q(|D ]R\}}
|
drt|dkr|dd  |kr|| }||dd   }||_||_qt D ]$\}}|| }|D ]}|||< qqttttttttd	ttttttttt d
	dt!it"t#t$t!t%dda&t&d t&d< t&' D ] }| D ]\}}	||	_(qxqldt)ia*t+ddD ]}t,t*d| < qt+ddD ]}t-t*d| < qddl.m/} |D ]\}}||}|rZ|0 \}}t1|}|| }	t2|	ds.i |	_3i |	_4||dd  |\}}||	j3|< ||	j4|< n|| }	|||\|	_3|	_4qd S )Nr   r   )otDataz([A-Za-z0-9]+)Format(\d+)$r  TZVarrL   )r   rK   rL   rG   rM   rN   rO   rP   )	r   rK   rL   rG   rM   rN   rO   rP   rQ   rG   )r   r   rK   rG   rM   )rr  rs  ZmortZmorxrs  ZJSTFsizer  zss%02dd   zcv%02d)buildConverters
converters)5rer  rb   globalsr   matchgroupr   rv  r  r  r   Z	NoVarTypeZVarType_equivalentsr   r  r)  rB  rK  ZContextSubstZChainContextSubstZExtensionSubstZReverseChainSingleSubstZ	SinglePosZPairPosZ
CursivePosZMarkBasePosZ
MarkLigPosZMarkMarkPosZ
ContextPosZChainContextPosZExtensionPosZNoncontextualMorphZRearrangementMorphZContextualMorphZLigatureMorphZInsertionMorphr  valuesr  r   r   r   r   r   ZotConvertersr  r  r0  r   r  convertersByName)r  r  Z	formatPat	namespacero   r{  Z	baseClassmZ
formatTyper:  r2  ZvarTypeZ	noVarTypebaserF  rG  Z
lookupEnumenumr   r  r   r  r#  r#   r#   r$   _buildClassesk  s    



& " 

r(  c                 C   s   | d krg S | j S d S r    )r   )r  r#   r#   r$   r    s    r  )`__doc__r  r'  r   	functoolsr   mathr   	itertoolscollectionsr   r   Z!fontTools.ttLib.tables.otTraverser   ZfontTools.misc.arrayToolsr   ZfontTools.misc.roundToolsr	   ZfontTools.misc.transformr
   r   ZfontTools.misc.textToolsr   r   r   ZfontTools.pens.boundsPenr   ZfontTools.pens.transformPenr   ZotBaser   r   r   r   r   Z fontTools.feaLib.lookupDebugInfor   r   loggingr   typingr   r   r   r   r   ZfontTools.ttLib.ttGlyphSetr   	getLoggerr'   r   objectr   r*   r,   rF   r   r   r   r   r   r   r   r   r   r  r   r  r  r  r)  r4  rB  rK  r[  rq  r  rg  r  r  re  r  r  r  ri  r!  r  r  r  r  r  r  r  r  r(  r  r#   r#   r#   r$   <module>   s   
UA  \I4PKjF_9.
 . 		U;G?;o