B
    Jd                 @   sD  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Zd dl	Z	d dl
Z
d dlZd dlmZ d dlmZmZmZmZ eeZd	Zyd dlZeeed
dZW n ek
r   Y nX ee d 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"e#e
$dd dks t%e		dj&dks:t%dG dd deZ'G dd deZ(G dd deZ)dd Z*dd  Z+d!d" Z,d#d$ Z-G d%d& d&eZ.G d'd( d(e.Z/G d)d* d*e/Z0e/e0d+Z1d,d- Z2e dGe.ee3 ee4 d.d/d0Z5d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@gZ6dAdB Z7e7 Z8G dCdD dDeZ9G dEdF dFeZ:dS )H    )OPTIONS)Tag	bytesjoin   )DefaultTable)IntEnumN)	lru_cache)Iterator
NamedTupleOptionalTupleFrepackz:USE_HARFBUZZ_REPACKERc               @   s   e Zd Zdd Zdd ZdS )OverflowErrorRecordc             C   s6   |d | _ |d | _|d | _|d | _|d | _d S )Nr   r            )	tableTypeLookupListIndexSubTableIndexitemName	itemIndex)selfZoverflowTuple r   O/var/www/html/venv/lib/python3.7/site-packages/fontTools/ttLib/tables/otBase.py__init__   s
    



zOverflowErrorRecord.__init__c          
   C   s$   t | jd| jd| jd| jd| jf	S )NzLookupIndex:zSubTableIndex:z	ItemName:z
ItemIndex:)strr   r   r   r   r   )r   r   r   r   __repr__"   s    zOverflowErrorRecord.__repr__N)__name__
__module____qualname__r   r   r   r   r   r   r      s   r   c               @   s   e Zd Zdd Zdd ZdS )OTLOffsetOverflowErrorc             C   s
   || _ d S )N)value)r   overflowErrorRecordr   r   r   r   &   s    zOTLOffsetOverflowError.__init__c             C   s
   t | jS )N)reprr!   )r   r   r   r   __str__)   s    zOTLOffsetOverflowError.__str__N)r   r   r   r   r$   r   r   r   r   r    %   s   r    c               @   s   e Zd ZdZdZdZdS )RepackerStater   r   r   N)r   r   r   PURE_FTHB_FTFT_FALLBACKr   r   r   r   r%   ,   s   
r%   c               @   sR   e Zd Z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dS )BaseTTXConverterzGeneric base class for TTX table converters. It functions as an
	adapter between the TTX (ttLib actually) table model and the model
	we use for OpenType tables, which is necessarily subtly different.
	c             C   s@   ddl m} t|| jd}t|| j}| | _| j|| dS )zFCreate an object from the binary data. Called automatically on access.r   )otTables)tableTagN) r*   OTTableReaderr+   getattrtable	decompile)r   datafontr*   reader
tableClassr   r   r   r0   G   s
    zBaseTTXConverter.decompilec       
   
   C   sh  d}|j t }| jdkr`|dkr0td| j n0ts`|dkrFtdn|dksRttd| j |dkr~tr~| jdkr~tj	}ntj
}d}d}xylt| jd	}| j|| |tj	kr| ||S |tj
kr| |S |tjkr| | td
 tj	}W q tk
r^ } zDd}| |||}	|j}|	r.w|tj	krLtd tj}n W dd}~X Y qX qW dS )z=Compiles the table into binary. Called automatically on save.N)ZGSUBZGPOSFz>hb.repack disabled, compiling '%s' with pure-python serializerTzNo module named 'uharfbuzz'z?uharfbuzz not found, compiling '%s' with pure-python serializer)NT)r+   zXRe-enabling sharing between extensions and switching back to harfbuzz+fontTools packing.zrHarfbuzz packing out of resolutions, disabling sharing between extensions and switching to fontTools only packing.)cfgUSE_HARFBUZZ_REPACKERr+   logdebughave_uharfbuzzImportErrorAssertionErrorr%   r'   r&   OTTableWriterr/   compiletryPackingHarfbuzztryPackingFontToolsr(   r    tryResolveOverflowr!   )
r   r2   overflowRecordZuse_hb_repackstatehb_first_error_loggedlastOverflowRecordwritereokr   r   r   r=   O   sV    












zBaseTTXConverter.compilec          
   C   s   yt d| j || jS  tttjfk
r } zJ|srt|j	 }t
|dkr^|d| 7 }t d| j| d}|jddS d }~X Y nX d S )Nzserializing '%s' with hb.repackr,   z: z`hb.repack failed to serialize '%s', attempting fonttools resolutions ; the error message was: %sTF)remove_duplicate)r7   r8   r+   getAllDataUsingHarfbuzz
ValueErrorMemoryErrorhbZRepackerErrortyper   r   warning
getAllData)r   rE   rC   rF   	error_msgr   r   r   r>      s    z#BaseTTXConverter.tryPackingHarfbuzzc             C   s   |  S )N)rO   )r   rE   r   r   r   r?      s    z$BaseTTXConverter.tryPackingFontToolsc             C   sz   d}||j kr|S |j }td| |jd krFddlm} |||}nddlm} |||}|rd|S ddlm} |||S )Nr   z+Attempting to fix OTLOffsetOverflowError %sr   )fixLookupOverFlows)fixSubTableOverFlows)r!   r7   infor   r*   rQ   rR   )r   r2   rF   rD   rG   rA   rQ   rR   r   r   r   r@      s    


z#BaseTTXConverter.tryResolveOverflowc             C   s   | j || d S )N)r/   toXML2)r   rE   r2   r   r   r   toXML   s    zBaseTTXConverter.toXMLc             C   sJ   ddl m} t| ds*t|| j}| | _| j|||| | j  d S )Nr   )r*   r/   )r,   r*   hasattrr.   r+   r/   fromXMLpopulateDefaults)r   nameattrscontentr2   r*   r4   r   r   r   rW      s    
zBaseTTXConverter.fromXMLTc             C   s   | j j|d d S )N)recurse)r/   ensureDecompiled)r   r\   r   r   r   r]      s    z!BaseTTXConverter.ensureDecompiledN)T)r   r   r   __doc__r0   r=   r>   r?   r@   rU   rW   r]   r   r   r   r   r)   @   s   Ur)   ir   z#Oops, file a bug against fonttools.c               @   s   e Zd ZdZdZd9d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 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/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 ZdS ):r-   z5Helper class to retrieve data from an OpenType table.)r1   offsetpos
localStater+   Nr   c             C   s"   || _ || _|| _|| _|| _d S )N)r1   r`   ra   rb   r+   )r   r1   rb   r`   r+   r   r   r   r      s
    zOTTableReader.__init__c             C   s   |  j |7  _ d S )N)ra   )r   countr   r   r   advance   s    zOTTableReader.advancec             C   s
   || _ d S )N)ra   )r   ra   r   r   r   seek   s    zOTTableReader.seekc             C   s$   |  | j| j| j| j}| j|_|S )N)	__class__r1   rb   r`   r+   ra   )r   otherr   r   r   copy   s    zOTTableReader.copyc             C   s    | j | }| | j| j|| jS )N)r`   rf   r1   rb   r+   )r   r`   r   r   r   getSubReader  s    
zOTTableReader.getSubReaderc             C   s6   | j }|| }td| | j|| \}|| _ |S )N>)ra   structunpackr1   )r   typecode
staticSizera   newposr!   r   r   r   	readValue  s
    zOTTableReader.readValuec             C   sH   | j }|||  }t|| j|| }tjdkr:|  || _ | S )Nbig)ra   arrayr1   sys	byteorderbyteswaptolist)r   rm   rn   rc   ra   ro   r!   r   r   r   	readArray  s    
 zOTTableReader.readArrayc             C   s   | j dddS )Nbr   )rn   )rp   )r   r   r   r   readInt8  s    zOTTableReader.readInt8c             C   s   | j dd|dS )Nrx   r   )rn   rc   )rw   )r   rc   r   r   r   readInt8Array  s    zOTTableReader.readInt8Arrayc             C   s   | j dddS )Nhr   )rn   )rp   )r   r   r   r   	readShort  s    zOTTableReader.readShortc             C   s   | j dd|dS )Nr{   r   )rn   rc   )rw   )r   rc   r   r   r   readShortArray  s    zOTTableReader.readShortArrayc             C   s   | j dddS )Nr_   r   )rn   )rp   )r   r   r   r   readLong  s    zOTTableReader.readLongc             C   s   | j dd|dS )Nr_   r   )rn   rc   )rw   )r   rc   r   r   r   readLongArray!  s    zOTTableReader.readLongArrayc             C   s   | j dddS )NBr   )rn   )rp   )r   r   r   r   	readUInt8$  s    zOTTableReader.readUInt8c             C   s   | j dd|dS )Nr   r   )rn   rc   )rw   )r   rc   r   r   r   readUInt8Array&  s    zOTTableReader.readUInt8Arrayc             C   s   | j dddS )NHr   )rn   )rp   )r   r   r   r   
readUShort)  s    zOTTableReader.readUShortc             C   s   | j dd|dS )Nr   r   )rn   rc   )rw   )r   rc   r   r   r   readUShortArray+  s    zOTTableReader.readUShortArrayc             C   s   | j dddS )NIr   )rn   )rp   )r   r   r   r   	readULong.  s    zOTTableReader.readULongc             C   s   | j dd|dS )Nr   r   )rn   rc   )rw   )r   rc   r   r   r   readULongArray0  s    zOTTableReader.readULongArrayc             C   s4   | j }|d }tdd| j||  \}|| _ |S )Nr   z>l    )ra   rk   rl   r1   )r   ra   ro   r!   r   r   r   
readUInt243  s
    zOTTableReader.readUInt24c                s    fddt |D S )Nc                s   g | ]}   qS r   )r   ).0_)r   r   r   
<listcomp>:  s    z1OTTableReader.readUInt24Array.<locals>.<listcomp>)range)r   rc   r   )r   r   readUInt24Array9  s    zOTTableReader.readUInt24Arrayc             C   s>   | j }|d }t| j|| }t|dks4t||| _ |S )Nr   )ra   r   r1   lenr;   )r   ra   ro   r!   r   r   r   readTag<  s    zOTTableReader.readTagc             C   s&   | j }|| }| j|| }|| _ |S )N)ra   r1   )r   rc   ra   ro   r!   r   r   r   readDataD  s
    zOTTableReader.readDatac             C   s(   | j r| j  nt }|||< || _ d S )N)rb   rh   dict)r   rY   r!   rB   r   r   r   __setitem__K  s    zOTTableReader.__setitem__c             C   s   | j o| j | S )N)rb   )r   rY   r   r   r   __getitem__P  s    zOTTableReader.__getitem__c             C   s   | j o|| j kS )N)rb   )r   rY   r   r   r   __contains__S  s    zOTTableReader.__contains__)Nr   N)r   r   r   r^   	__slots__r   rd   re   rh   ri   rp   rw   ry   rz   r|   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r-      s8   
r-   c               @   sd  e Zd ZdZdUddZedd Zej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dVddZdd Zd d! Zd"d# ZdWd%d&ZdXd'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dCdD Z$dEdF Z%dGdH Z&dIdJ Z'dKdL Z(dYdMdNZ)dOdP Z*dQdR Z+dSdT Z,dS )Zr<   z=Helper class to gather and assemble data for OpenType tables.Nr   c             C   s(   g | _ d | _|| _|| _|| _d | _d S )N)itemsra   rb   r+   
offsetSizeparent)r   rb   r+   r   r   r   r   r   [  s    zOTTableWriter.__init__c             C   s
   | j dkS )Nr   )r   )r   r   r   r   
longOffsete  s    zOTTableWriter.longOffsetc             C   s   |rdnd| _ d S )Nr   r   )r   )r   r!   r   r   r   r   i  s    c             C   s(   | j r| j  nt }|||< || _ d S )N)rb   rh   r   )r   rY   r!   rB   r   r   r   r   m  s    zOTTableWriter.__setitem__c             C   s
   | j | S )N)rb   )r   rY   r   r   r   r   r  s    zOTTableWriter.__getitem__c             C   s   | j |= d S )N)rb   )r   rY   r   r   r   __delitem__u  s    zOTTableWriter.__delitem__c             C   sP   d}xF| j D ]<}t|dr&||j7 }qt|dr<||j7 }q|t| }qW |S )z<Return the length of this table in bytes, without subtables.r   getCountDatagetData)r   rV   sizer   r   )r   litemr   r   r   getDataLengthz  s    

zOTTableWriter.getDataLengthc          	   C   s   t | j}| j}t|}xt|D ]}|| }t|dr"|jdkrVt|j| ||< q"|jdkryt|j| ||< W q t	j
k
r   | |}t|Y qX q"|jdkrt|j| ||< q"t|jq"W t|S )z;Assemble the data for this writer/table, without subtables.r   r   r   r   )listr   ra   r   r   rV   r   	packULong
packUShortrk   errorgetOverflowErrorRecordr    
packUInt24rJ   r   )r   r   ra   numItemsr_   r   r"   r   r   r   r     s$    





zOTTableWriter.getDatac             C   sf   t | j}tttd}xFt|D ]:\}}t|dr |j|krP||j d||< q t|jq W t	|S )zFAssemble the data for this writer/table with all offset field set to 0)r   r   r   r   r   )
r   r   r   r   r   	enumeraterV   r   rJ   r   )r   r   Z	packFuncsr_   r   r   r   r   getDataForHarfbuzz  s    


z OTTableWriter.getDataForHarfbuzzc             C   s
   t | jS )N)hashr   )r   r   r   r   __hash__  s    zOTTableWriter.__hash__c             C   s   |  |}|tkr|S | S )N)__eq__NotImplemented)r   rg   resultr   r   r   __ne__  s    
zOTTableWriter.__ne__c             C   s,   t | t |krtS | j|jko*| j|jkS )N)rM   r   r   r   )r   rg   r   r   r   r     s    zOTTableWriter.__eq__Fc             C   s   t | d}t | d}|r |s i }| j}xdtt|D ]T}|| }t |drX| ||< q4t |dr4|j||d |s4||| ||< }q4W t|| _d S )N	Extension	DontSharer   r   )shareExtension)rV   r   r   r   r   _doneWriting
setdefaulttuple)r   internedTablesr   isExtensionZ	dontSharer   r_   r   r   r   r   r     s    



zOTTableWriter._doneWritingc             C   s$  d|t | < t| j}tt|}|  t| d}|}|r\|d k	sLtd|d i   }}}d}t| drx0t|D ]$}	| j|	 }
t|
dd dkrtd}P qtW t |
|kr|
	||| n x\|D ]T}	| j|	 }
t|
dsq|r|	d	krt|
dd dkrqt |
|kr|
	||| qqW |
|  d S )
NTr   zUProgram or XML editing error. Extension subtables cannot contain extensions subtablesFsortCoverageLastrY   Coverager   r   )idr   r   r   r   reverserV   r;   r.   _gatherTablesappend)r   tables	extTablesdoner   ZiRanger   Z
selfTablesr   r_   r   r   r   r   r     s8    	






zOTTableWriter._gatherTablesc             C   s  g }g }|}x|D ]}	| dd|	f qW d}
d}t| drxft| jD ]X\}}t|dd dkrHd}
t||kr|||||| }}n|t| }| | P qHW d}d}xt| jD ]\}}t|dr|}n&t|dr||j7 }qn|t| }qt||kr|||||| }}n|t| }||j	|f}| | ||j	7 }qW | |  | ||f |d	7 }||t| < |
r|
  |S )
Nr   Fr   rY   r   Tr   r   r   )r   rV   r   r   r.   r   _gatherGraphForHarfbuzzr   r   r   pop)r   r   obj_listr   objidxvirtual_edgesZ
real_linksZvirtual_linksZitem_idxidxr   Zcoverage_idxr_   r   Z	child_idxZ
offset_posra   Z	real_edger   r   r   r     sN    







z%OTTableWriter._gatherGraphForHarfbuzzc             C   s   i }| j |dd g }g }i }d}g }| ||||| d}x|D ]}	||	_||	  }qBW g }
x|D ]}	|	 }|
| qfW ttdrtt	||
|S t
|
|S dS )a  The Whole table is represented as a Graph.
                Assemble graph data and call Harfbuzz repacker to pack the table.
                Harfbuzz repacker is faster and retain as much sub-table sharing as possible, see also:
                https://github.com/harfbuzz/harfbuzz/blob/main/docs/repacker.md
                The input format for hb.repack() method is explained here:
                https://github.com/harfbuzz/uharfbuzz/blob/main/src/uharfbuzz/_harfbuzz.pyx#L1149
                T)r   r   repack_with_tagN)r   r   ra   r   r   r   rV   rL   r   r   r   )r   r+   r   r   r   r   r   r   ra   r/   r1   	tableDatar   r   r   rI   K  s&    


z%OTTableWriter.getAllDataUsingHarfbuzzTc       
      C   s   |ri }|  | g }g }i }| ||| |  |  d}x|D ]}||_||  }qFW x|D ]}||_||  }qfW g }x|D ]}| }	||	 qW x|D ]}| }	||	 qW t|S )z+Assemble all data, including all subtables.r   )r   r   r   ra   r   r   r   r   )
r   rH   r   r   r   r   ra   r/   r1   r   r   r   r   rO   l  s0    




zOTTableWriter.getAllDatac             C   s   | j | j| j|d}| |_|S )N)r   )rf   rb   r+   r   )r   r   Z	subwriterr   r   r   getSubWriter  s    zOTTableWriter.getSubWriterc             C   s   | j td| | d S )Nrj   )r   r   rk   pack)r   rm   r!   r   r   r   
writeValue  s    zOTTableWriter.writeValuec             C   s2   t  ||}tjdkr|  | j|  d S )Nrq   )rr   rs   rt   ru   r   r   tobytes)r   rm   valuesar   r   r   
writeArray  s    
 zOTTableWriter.writeArrayc             C   s6   d|  krdk sn t || jtd| d S )Ni   z>b)r;   r   r   rk   r   )r   r!   r   r   r   	writeInt8  s    zOTTableWriter.writeInt8c             C   s   |  d| d S )Nrx   )r   )r   r   r   r   r   writeInt8Array  s    zOTTableWriter.writeInt8Arrayc             C   s6   d|  krdk sn t || jtd| d S )Ni i   z>h)r;   r   r   rk   r   )r   r!   r   r   r   
writeShort  s    zOTTableWriter.writeShortc             C   s   |  d| d S )Nr{   )r   )r   r   r   r   r   writeShortArray  s    zOTTableWriter.writeShortArrayc             C   s   | j td| d S )Nz>i)r   r   rk   r   )r   r!   r   r   r   	writeLong  s    zOTTableWriter.writeLongc             C   s   |  d| d S )Nr_   )r   )r   r   r   r   r   writeLongArray  s    zOTTableWriter.writeLongArrayc             C   s6   d|  krdk sn t || jtd| d S )Nr      z>B)r;   r   r   rk   r   )r   r!   r   r   r   
writeUInt8  s    zOTTableWriter.writeUInt8c             C   s   |  d| d S )Nr   )r   )r   r   r   r   r   writeUInt8Array  s    zOTTableWriter.writeUInt8Arrayc             C   s6   d|  krdk sn t || jtd| d S )Nr   i   z>H)r;   r   r   rk   r   )r   r!   r   r   r   writeUShort  s    zOTTableWriter.writeUShortc             C   s   |  d| d S )Nr   )r   )r   r   r   r   r   writeUShortArray  s    zOTTableWriter.writeUShortArrayc             C   s   | j td| d S )Nz>I)r   r   rk   r   )r   r!   r   r   r   
writeULong  s    zOTTableWriter.writeULongc             C   s   |  d| d S )Nr   )r   )r   r   r   r   r   writeULongArray  s    zOTTableWriter.writeULongArrayc             C   sB   d|  krdk sn t |td|}| j|dd   d S )Nr   i   z>Lr   )r;   rk   r   r   r   )r   r!   rx   r   r   r   writeUInt24  s    zOTTableWriter.writeUInt24c             C   s   x|D ]}|  | qW d S )N)r   )r   r   r!   r   r   r   writeUInt24Array  s    
zOTTableWriter.writeUInt24Arrayc             C   s0   t | }t|dks t|| j| d S )Nr   )r   r   r   r;   r   r   )r   tagr   r   r   writeTag  s    zOTTableWriter.writeTagc             C   s   | j | d S )N)r   r   )r   	subWriterr   r   r   writeSubTable  s    zOTTableWriter.writeSubTablec             C   s    t ||||d}| j| |S )N)r   r!   )CountReferencer   r   )r   r/   rY   r   r!   refr   r   r   writeCountReference  s    z!OTTableWriter.writeCountReferencec             C   s    t j|f|  }| j| d S )N)rk   r   r   r   )r   formatr   r1   r   r   r   writeStruct  s    zOTTableWriter.writeStructc             C   s   | j | d S )N)r   r   )r   r1   r   r   r   	writeData  s    zOTTableWriter.writeDatac             C   s  d  } } }}| j dkr"|j}n| j dkr:| j}|j}nt|dd}t|drV|j}| j dkrp| jj}| j}n| j dkr| jjj}| jj}npd| j |g}| j}x(|r|j d	krd|j |g}|j}qW |r|j dkr|jjj}|jj}n|jj}|j}t| j||||fS )
NZ
LookupListZLookuprY   z<none>repeatIndexSubTableExtSubTable.)r   r   )rY   r   r.   rV   r   joinr   r+   )r   r   r   r   r   r   p1r   r   r   r     s6    










z$OTTableWriter.getOverflowErrorRecord)NNr   )F)T)r   )r   N)-r   r   r   r^   r   propertyr   setterr   r   r   r   r   r   r   r   r   r   r   r   rI   rO   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r<   W  sR   


$75!
#

r<   c               @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )r   z8A reference to a Count value, not a count of references.Nc             C   s(   || _ || _|| _|d k	r$| | d S )N)r/   rY   r   setValue)r   r/   rY   r   r!   r   r   r   r      s
    zCountReference.__init__c             C   sD   | j }| j}|| d kr"|||< n|| |ks@t||| |fd S )N)r/   rY   r;   )r   r!   r/   rY   r   r   r   r     s
    
zCountReference.setValuec             C   s   | j | j S )N)r/   rY   )r   r   r   r   getValue  s    zCountReference.getValuec             C   s.   | j | j }|d krd}tttd| j |S )Nr   )r   r   r   )r/   rY   	packUInt8r   r   r   )r   vr   r   r   r     s     zCountReference.getCountData)NN)r   r   r   r^   r   r   r   r   r   r   r   r   r     s
   
r   c             C   s   t d| S )Nz>B)rk   r   )r!   r   r   r   r     s    r   c             C   s   t d| S )Nz>H)rk   r   )r!   r   r   r   r     s    r   c             C   s*   d|   krdk sn t | td| S )Nr   l        z>I)r;   rk   r   )r!   r   r   r   r     s    r   c             C   s2   d|   krdk sn t | td| dd  S )Nr   i   z>Ir   )r;   rk   r   )r!   r   r   r   r     s    r   c               @   s   e Zd ZdZdd Zd)ddZedd Zd	d
 Zdd Z	d*ddZ
dd Zdd Zdd Zdd Zd+ddZdd Zdd Zdd Zd d! ZG d"d# d#eZee d$d%d&Zd'd( ZdS ),	BaseTablez0Generic base class for all OpenType (sub)tables.c             C   s@   | j d}|r4| `| j}| `| || t| |S t|d S )Nr3   )__dict__getr3   r2   r0   r.   AttributeError)r   attrr3   r2   r   r   r   __getattr__(  s    
zBaseTable.__getattr__Fc             C   sP   | j d}|r*| `| j}| `| || |rLx|  D ]}|j| q8W d S )Nr3   )r   r   r3   r2   r0   iterSubTablesr!   r]   )r   r\   r3   r2   Zsubtabler   r   r   r]   3  s    zBaseTable.ensureDecompiledc             C   sd   d}xZ| j D ]P}||}|tkr&tS d}|jrP|j|krL||j |j }ntS ||| 7 }qW |S )Nr   r   )
convertersgetRecordSizer   repeataux)clsr3   Z	totalSizeconvr   
countValuer   r   r   r   >  s    
 
zBaseTable.getRecordSizec             C   s   | j S )N)r   )r   r   r   r   getConvertersM  s    zBaseTable.getConvertersc             C   s
   | j | S )N)convertersByName)r   rY   r   r   r   getConverterByNameP  s    zBaseTable.getConverterByNameNc          	   C   s   x|   D ]}|jrt| |js.t| |jg  tt| |j|j }y| |j}t| |j| W q t	k
r   |r|j|kr||j 
| Y qX q
|jrt|jd | jsq
t| |jrq
t|drt| |jd  t|dr
t| |j|j q
W d S )NZwriteNullOffsetDEFAULT)r  r  rV   rY   setattrr   r.   r  r  KeyErrorr   evalr   r	  )r   Z
propagatorr  r  Z
count_convr   r   r   rX   S  s&    

zBaseTable.populateDefaultsc             C   s  |  | i }|| _x`|  D ]R}|jdkrB||j|d }|jdkr^||j|d }|jdkrv||d }|jdkr||j|d }y|jrt|jtr|j}n |j|kr||j }n
||j }||j	7 }|
||||||j< nF|j	r
t|j	d |s
w ||||||j< |jr6||j ||j< W q  tk
rr } z|j}|j|f |_ W d d }~X Y q X q W t| d	r| || n| j| | `d S )
Nr   
LookupTyper   ZExtensionLookupTypeZFeatureParamsZ
FeatureTagZ	SubStructZ	MorphTypepostRead)
readFormatZ_BaseTable__rawTabler  rY   ZgetConverterr+   r  
isinstanceintr  rw   r  readisPropagated	ExceptionargsrV   r  r   update)r   r3   r2   r/   r  r  rF   rY   r   r   r   r0   n  sJ    










zBaseTable.decompilec             C   s  |    t| dr8t| d }| |}|o4t| d}nd}| j }x<|  D ]0}|jrP|jrP||j	}t
|trP|||j	< qPW t| drd|_t| drd|_t| jdr|d | jj | | x.|  D ] }||j	}|jr|d krg }t||j }t
|jtrBt||jksptd	|jt|f n.|j|kr`t||j|d
 n||j | y||||| W n: tk
r } z|j|j	d f |_ W d d }~X Y nX q|jr,t
|tr|}	|j|	_||	 |	 ||j	< n|||j	|j}	d ||j	< |jr|	||j	< q|jrn|j	|krJd ||j	< |||j	|j||j	 }	|	|d< q|jrt |jd |sqy|!|||| W nL tk
r } z,|d k	r|jj"n|j	}
|j|
f |_ W d d }~X Y nX |jr|||j	< qW |r| `#d S )NpreWriteFormatFr   r   r   Tr  zexpected %d values, got %d)r!   z[])$r]   rV   r  r   rh   r  ZisCountr  r   rY   r  r   r   r   rf   r   r  writeFormatr  r   r  r  r;   r   r  r  rn   r   r   r   r   ZisLookupTyper  writer   r  )r   rE   r2   ZdeleteFormatr/   r  r!   r  rF   r   rY   r   r   r   r=     s|    






(




zBaseTable.compilec             C   s   d S )Nr   )r   r3   r   r   r   r    s    zBaseTable.readFormatc             C   s   d S )Nr   )r   rE   r   r   r   r    s    zBaseTable.writeFormatc             C   sl   |r|n| j j}|d krg }t| dr6|d| jfg }||| |  | || || |  d S )Nr  )rf   r   rV   r  begintagnewlinerT   endtag)r   	xmlWriterr2   rZ   rY   Z	tableNamer   r   r   rU     s    

zBaseTable.toXMLc          
   C   s   x|   D ]}|jr\t| |jg }xttt|D ]&}|| }|||||jd|fg q0W q
|jrvt|jd t	| svq
t| |jd }|||||jg  q
W d S )Nindex)
r  r  r.   rY   r   r   ZxmlWriter  r  vars)r   r  r2   r  r!   r_   r   r   r   r   rT     s    zBaseTable.toXML2c             C   s   y|  |}W n tk
r$    Y nX ||||}|jrnt| |jd }|d krbg }t| |j| || nt| |j| d S )N)r  r  ZxmlReadr  r.   rY   r
  r   )r   rY   rZ   r[   r2   r  r!   seqr   r   r   rW     s    zBaseTable.fromXMLc             C   s   |  |}|tkr|S | S )N)r   r   )r   rg   r   r   r   r   r   +  s    
zBaseTable.__ne__c             C   s0   t | t |krtS |   |  | j|jkS )N)rM   r   r]   r   )r   rg   r   r   r   r   /  s
    zBaseTable.__eq__c               @   s2   e Zd ZU dZeed< ded< dZee ed< dS )zBaseTable.SubTableEntryzSee BaseTable.iterSubTables()rY   r   r!   Nr  )	r   r   r   r^   r   __annotations__r  r   r  r   r   r   r   SubTableEntry8  s   
r#  )returnc             #   st   xn  D ]b}|j t d}|dkr*q
t|trD |V  q
t|tr
 fddt|D E dH  q
W dS )a  Yield (name, value, index) namedtuples for all subtables of current table.

		A sub-table is an instance of BaseTable (or subclass thereof) that is a child
		of self, the current parent table.
		The tuples also contain the attribute name (str) of the of parent table to get
		a subtable, and optionally, for lists of subtables (i.e. attributes associated
		with a converter that has a 'repeat'), an index into the list containing the
		given subtable value.
		This method can be useful to traverse trees of otTables.
		Nc             3   s,   | ]$\}}t |trj ||d V  qdS ))r  N)r  r   r#  )r   r_   r   )rY   r   r   r   	<genexpr>R  s   z*BaseTable.iterSubTables.<locals>.<genexpr>)r  rY   r.   r  r   r#  r   r   )r   r  r!   r   )rY   r   r   r   >  s    

zBaseTable.iterSubTablesc             C   s
   t | jS )N)getVariableAttrsrf   )r   r   r   r   r&  X  s    zBaseTable.getVariableAttrs)F)N)NN)r   r   r   r^   r   r]   classmethodr   r  r  rX   r0   r=   r  r  rU   rT   rW   r   r   r
   r#  r	   r   r&  r   r   r   r   r   $  s&   

-^
	r   c               @   sN   e Zd ZdZedd Zdd Zdd Zdd	 Zd
d Z	dddZ
dd ZdS )FormatSwitchingBaseTablezsMinor specialization of BaseTable, for tables that have multiple
	formats, eg. CoverageFormat1 vs. CoverageFormat2.c             C   s   t S )N)r   )r  r3   r   r   r   r   a  s    z&FormatSwitchingBaseTable.getRecordSizec             C   s0   y
| j }W n tk
r   g S X | j| j g S )N)r  r   r   r   )r   fmtr   r   r   r  e  s
    
z&FormatSwitchingBaseTable.getConvertersc             C   s   | j | j | S )N)r  r  )r   rY   r   r   r   r  q  s    z+FormatSwitchingBaseTable.getConverterByNamec             C   s   |  | _d S )N)r   r  )r   r3   r   r   r   r  t  s    z#FormatSwitchingBaseTable.readFormatc             C   s   | | j d S )N)r   r  )r   rE   r   r   r   r  w  s    z$FormatSwitchingBaseTable.writeFormatNc             C   s   t | |||| d S )N)r   rU   )r   r  r2   rZ   rY   r   r   r   rU   z  s    zFormatSwitchingBaseTable.toXMLc             C   s   t | j| jS )N)r&  rf   r  )r   r   r   r   r&  }  s    z)FormatSwitchingBaseTable.getVariableAttrs)NN)r   r   r   r^   r'  r   r  r  r  r  rU   r&  r   r   r   r   r(  \  s   
r(  c               @   s   e Zd Zdd Zdd ZdS )UInt8FormatSwitchingBaseTablec             C   s   |  | _d S )N)r   r  )r   r3   r   r   r   r    s    z(UInt8FormatSwitchingBaseTable.readFormatc             C   s   | | j d S )N)r   r  )r   rE   r   r   r   r    s    z)UInt8FormatSwitchingBaseTable.writeFormatN)r   r   r   r  r  r   r   r   r   r*    s   r*  )Zuint16Zuint8c             C   s0   yt |  S  tk
r*   td| Y nX d S )NzUnsupported format type: )formatSwitchingBaseTablesr  	TypeError)Z
formatTyper   r   r    getFormatSwitchingBaseTableClass  s    r-  )r  r)  r$  c             C   s   t | tst| t | tr@|dkr4td| j | j| }n| j}d|krRdS i }x,| D ] \}}| }|dk	r`|||< q`W tt	||j
dS )zReturn sequence of variable table field names (can be empty).

	Attributes are deemed "variable" when their otData.py's description contain
	'VarIndexBase + {offset}', e.g. COLRv1 PaintVar* tables.
	Nz''fmt' is required for format-switching ZVarIndexBaser   )key)
issubclassr   r,  r(  r   r  r   ZgetVarIndexOffsetr   sortedr   )r  r)  r   ZvarAttrsrY   r  r`   r   r   r   r&    s    

r&  )r   Z
XPlacementr   r   )r   Z
YPlacementr   r   )r   ZXAdvancer   r   )   ZYAdvancer   r   )   Z
XPlaDevicer   r   )    Z
YPlaDevicer   r   )@   Z
XAdvDevicer   r   )r   Z
YAdvDevicer   r   )r   Z	Reserved1r   r   )i   Z	Reserved2r   r   )i   Z	Reserved3r   r   )i   Z	Reserved4r   r   )i   Z	Reserved5r   r   )i    Z	Reserved6r   r   )i @  Z	Reserved7r   r   )i   Z	Reserved8r   r   c              C   s,   i } x"t D ]\}}}}|||f| |< q
W | S )N)valueRecordFormat)dmaskrY   isDevicesignedr   r   r   
_buildDict  s    r:  c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ValueRecordFactoryz6Given a format code, this object convert ValueRecords.c             C   s<   g }x,t D ]$\}}}}||@ r
||||f q
W || _d S )N)r5  r   r   )r   valueFormatr   r7  rY   r8  r9  r   r   r   r     s
    zValueRecordFactory.__init__c             C   s
   t | jS )N)r   r   )r   r   r   r   __len__  s    zValueRecordFactory.__len__c             C   s   | j }|sd S t }xp|D ]h\}}}|r2| }n| }|rv|rrddlm}	 ||}
t|	| }||
| nd }t	||| qW |S )Nr   )r*   )
r   ValueRecordr|   r   r,   r*   ri   r.   r0   r
  )r   r3   r2   r   valueRecordrY   r8  r9  r!   r*   Z	subReaderr   r   r   readValueRecord  s"    

z"ValueRecordFactory.readValueRecordc       	      C   st   xn| j D ]d\}}}t||d}|rR|rF| }|| ||| ql|d q|rb|| q|| qW d S )Nr   )r   r.   r   r   r=   r   r   )	r   rE   r2   r?  rY   r8  r9  r!   r   r   r   r   writeValueRecord  s    
z#ValueRecordFactory.writeValueRecordN)r   r   r   r^   r   r=  r@  rA  r   r   r   r   r;    s
   r;  c               @   sH   e Zd ZdddZdd Zdd Zddd	Zd
d Zdd Zdd Z	dS )r>  Nc       	      C   s   |d k	rtx0t D ](\}}}}||@ rt| ||r0d nd qW |d k	rxD|j D ] \}}t| |sbqNt| || qNW n|d k	r|j | _d S )Nr   )r5  r
  r   r   rV   rh   )	r   r<  srcr7  rY   r8  r9  r.  valr   r   r   r     s    
zValueRecord.__init__c             C   s,   d}x"| j  D ]}|t| d B }qW |S )Nr   )r   keysvalueRecordFormatDict)r   r   rY   r   r   r   	getFormat  s    zValueRecord.getFormatc             C   s4   d}x*| j  D ]\}}|r|t| d B }qW |S )Nr   )r   r   rE  )r   r   rY   r!   r   r   r   getEffectiveFormat   s
    zValueRecord.getEffectiveFormatc             C   s  |d krg }nt |}x:td d D ]*\}}}}	t| |r$||t| |f q$W g }
xFtdd D ]6\}}}}	t| |rdt| |}|d k	rd|
||f qdW |
r||| |  x(|
D ] \}}|d k	r|j|||d qW || |  n|	|| |  d S )Nr   r1  )rY   )
r   r5  rV   r   r.   r  r  rU   r  Z	simpletag)r   r  r2   Z	valueNamerZ   ZsimpleItemsr7  rY   r8  r   ZdeviceItemsZdeviceZdeviceRecordr   r   r   rU   '  s,    




zValueRecord.toXMLc             C   s   ddl m} x$| D ]\}}t| |t| qW xn|D ]f}t|tsHq8|\}}}t|| }	x2|D ]*}
t|
tstqd|
\}}}|	|||| qdW t| ||	 q8W d S )Nr   )r*   )	r,   r*   r   r
  r  r  r   r.   rW   )r   rY   rZ   r[   r2   r*   kr   elementr!   Zelem2Zname2Zattrs2Zcontent2r   r   r   rW   A  s    





zValueRecord.fromXMLc             C   s   |  |}|tkr|S | S )N)r   r   )r   rg   r   r   r   r   r   Q  s    
zValueRecord.__ne__c             C   s    t | t |krtS | j|jkS )N)rM   r   r   )r   rg   r   r   r   r   U  s    zValueRecord.__eq__)NN)N)
r   r   r   r   rF  rG  rU   rW   r   r   r   r   r   r   r>  	  s   

r>  )N);ZfontTools.configr   ZfontTools.misc.textToolsr   r   r   enumr   rs   rr   rk   logging	functoolsr   typingr	   r
   r   r   	getLoggerr   r7   r9   Z	uharfbuzzrL   callabler.   r:   r6   objectr   r  r    r%   r)   r   r   r;   itemsizer-   r<   r   r   r   r   r   r   r(  r*  r+  r-  r  r   r&  r5  r:  rE  r;  r>  r   r   r   r   <module>   s   
 )l   *  :%	#3