o
    l^Ufk                  	   @   s6  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zd dlZeeed
dZW n	 eyZ   Y nw 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sJ e		dj%dksJ d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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 d<d0e.d1ee3 d2ee4 fd3d4Z5g d5Z6d6d7 Z7e7 Z8G d8d9 d9eZ9G d:d; d;eZ:dS )=    )OPTIONS)Tag	bytesjoin   )DefaultTable)IntEnumN)	lru_cache)Iterator
NamedTupleOptionalTupleFrepackz:USE_HARFBUZZ_REPACKERc                   @      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   =lib/python3.10/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                   @   r   )OTLOffsetOverflowErrorc                 C   
   || _ d S Nvalue)r   overflowErrorRecordr   r   r   r   5      
zOTLOffsetOverflowError.__init__c                 C   
   t | jS r$   )reprr&   r   r   r   r   __str__8   r(   zOTLOffsetOverflowError.__str__N)r   r    r!   r   r+   r   r   r   r   r"   4       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) r3   OTTableReaderr5   getattrtable	decompile)r   datafontr3   reader
tableClassr   r   r   r:   W   s
   zBaseTTXConverter.decompilec           
   
   C   sj  d}|j t }| jdv r/|du rtd| j nts/|du r"td|du s(J td| j |dv r>tr>| jdv r>tj}ntj	}d}d}	 z8t
| jd	}| j|| |tjkr`| ||W S |tj	krk| |W S |tjkr}| | td
 tj}W n5 ty } z)d}| |||}	|j}|	rW Y d}~qE|tju rtd tj}n W Y d}~nd}~ww qF)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)NTr4   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.)ZcfgUSE_HARFBUZZ_REPACKERr5   logdebughave_uharfbuzzImportErrorr-   r/   r.   OTTableWriterr9   compiletryPackingHarfbuzztryPackingFontToolsr0   r"   tryResolveOverflowr&   )
r   r<   overflowRecordZuse_hb_repackstatehb_first_error_loggedlastOverflowRecordwritereokr   r   r   rE   `   sn   







zBaseTTXConverter.compilec              
   C   s   zt d| j || jW S  tttjfyI } z+|s9t|j	 }t
|dkr/|d| 7 }t d| j| d}|jddW  Y d }~S d }~ww )Nzserializing '%s' with hb.repackr6   z: z`hb.repack failed to serialize '%s', attempting fonttools resolutions ; the error message was: %sTF)remove_duplicate)r@   rA   r5   getAllDataUsingHarfbuzz
ValueErrorMemoryErrorhbZRepackerErrortyper   r   Zwarning
getAllData)r   rM   rK   rN   Z	error_msgr   r   r   rF      s"   z#BaseTTXConverter.tryPackingHarfbuzzc                 C   s   |  S r$   )rV   r   rM   r   r   r   rG      s   z$BaseTTXConverter.tryPackingFontToolsc                 C   sz   d}||j kr	|S |j }td| |jd u r#ddlm} |||}nddlm} |||}|r2|S ddlm} |||S )Nr   z+Attempting to fix OTLOffsetOverflowError %sr   )fixLookupOverFlows)fixSubTableOverFlows)r&   r@   infor   r3   rX   rY   )r   r<   rN   rL   rO   rI   rX   rY   r   r   r   rH      s   



z#BaseTTXConverter.tryResolveOverflowc                 C   s   | j || d S r$   )r9   toXML2)r   rM   r<   r   r   r   toXML      zBaseTTXConverter.toXMLc                 C   sJ   ddl m} t| dst|| j}| | _| j|||| | j  d S )Nr   r2   r9   )r6   r3   hasattrr8   r5   r9   fromXMLpopulateDefaults)r   nameattrscontentr<   r3   r>   r   r   r   r_      s   
zBaseTTXConverter.fromXMLTc                 C   s   | j j|d d S )N)recurse)r9   ensureDecompiled)r   rd   r   r   r   re      r]   z!BaseTTXConverter.ensureDecompiledNT)r   r    r!   __doc__r:   rE   rF   rG   rH   r\   r_   re   r   r   r   r   r1   Q   s    	[	r1   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 ):r7   z5Helper class to retrieve data from an OpenType table.r;   offsetpos
localStater5   Nr   c                 C   s"   || _ || _|| _|| _|| _d S r$   ri   )r   r;   rl   rj   r5   r   r   r   r   
  
   
zOTTableReader.__init__c                 C   s   |  j |7  _ d S r$   rk   r   countr   r   r   advance  r]   zOTTableReader.advancec                 C   r#   r$   rn   )r   rk   r   r   r   seek  r(   zOTTableReader.seekc                 C   s$   |  | j| j| j| j}| j|_|S r$   )	__class__r;   rl   rj   r5   rk   r   otherr   r   r   copy  s   zOTTableReader.copyc                 C   s    | j | }| | j| j|| jS r$   )rj   rs   r;   rl   r5   )r   rj   r   r   r   getSubReader  s   
zOTTableReader.getSubReaderc                 C   s6   | j }|| }td| | j|| \}|| _ |S N>rk   structunpackr;   )r   typecode
staticSizerk   newposr&   r   r   r   	readValue   s
   zOTTableReader.readValuec                 C   sH   | j }|||  }t|| j|| }tjdkr|  || _ | S NZbig)rk   arrayr;   sys	byteorderbyteswaptolist)r   r}   r~   rp   rk   r   r&   r   r   r   	readArray'  s   
zOTTableReader.readArrayc                 C      | j dddS )Nbr   r~   r   r   r   r   r   readInt80     zOTTableReader.readInt8c                 C      | j dd|dS )Nr   r   r~   rp   r   ro   r   r   r   readInt8Array3     zOTTableReader.readInt8Arrayc                 C   r   )Nhr   r   r   r   r   r   r   	readShort6  r   zOTTableReader.readShortc                 C   r   )Nr   r   r   r   ro   r   r   r   readShortArray9  r   zOTTableReader.readShortArrayc                 C   r   )Nrh   r   r   r   r   r   r   r   readLong<  r   zOTTableReader.readLongc                 C   r   )Nrh   r   r   r   ro   r   r   r   readLongArray?  r   zOTTableReader.readLongArrayc                 C   r   )NBr   r   r   r   r   r   r   	readUInt8B  r   zOTTableReader.readUInt8c                 C   r   )Nr   r   r   r   ro   r   r   r   readUInt8ArrayE  r   zOTTableReader.readUInt8Arrayc                 C   r   )NHr   r   r   r   r   r   r   
readUShortH  r   zOTTableReader.readUShortc                 C   r   )Nr   r   r   r   ro   r   r   r   readUShortArrayK  r   zOTTableReader.readUShortArrayc                 C   r   )NIr   r   r   r   r   r   r   	readULongN  r   zOTTableReader.readULongc                 C   r   )Nr   r   r   r   ro   r   r   r   readULongArrayQ  r   zOTTableReader.readULongArrayc                 C   s4   | j }|d }tdd| j||  \}|| _ |S )Nr   z>l    rz   r   rk   r   r&   r   r   r   
readUInt24T  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>)rangero   r   r   r   readUInt24Array[     zOTTableReader.readUInt24Arrayc                 C   s>   | j }|d }t| j|| }t|dksJ ||| _ |S Nr   )rk   r   r;   lenr   r   r   r   readTag^  s   zOTTableReader.readTagc                 C   s&   | j }|| }| j|| }|| _ |S r$   )rk   r;   )r   rp   rk   r   r&   r   r   r   readDataf  s
   zOTTableReader.readDatac                 C   (   | j r| j  nt }|||< || _ d S r$   rl   rv   dictr   ra   r&   rJ   r   r   r   __setitem__m     
zOTTableReader.__setitem__c                 C   s   | j o| j | S r$   rl   r   ra   r   r   r   __getitem__r  r   zOTTableReader.__getitem__c                 C   s   | j o|| j v S r$   r   r   r   r   r   __contains__u  r   zOTTableReader.__contains__)Nr   N)r   r    r!   rg   	__slots__r   rq   rr   rv   rw   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   r7     s:    
	r7   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )OffsetToWriterc                 C   s   || _ || _d S r$   )	subWriter
offsetSizer   r   r   r   r   r   r   z  s   
zOffsetToWriter.__init__c                 C   s,   t | t |kr
tS | j|jko| j|jkS r$   )rU   NotImplementedr   r   rt   r   r   r   __eq__~  s   zOffsetToWriter.__eq__c                 C   s   t | j| jfS r$   )hashr   r   r   r   r   r   __hash__  s   zOffsetToWriter.__hash__N)r   r    r!   r   r   r   r   r   r   r   r   y  s    r   c                   @   sH  e Zd ZdZdRd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dSddZdd Zdd Zdd ZdTd!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d9d: Zd;d< Zd=d> Z d?d@ Z!dAdB Z"dCdD Z#dEdF Z$dGdH Z%dUdJdKZ&dLdM Z'dNdO Z(dPdQ Z)dS )VrD   z=Helper class to gather and assemble data for OpenType tables.Nc                 C   s"   g | _ d | _|| _|| _d | _d S r$   )itemsrk   rl   r5   parent)r   rl   r5   r   r   r   r     rm   zOTTableWriter.__init__c                 C   r   r$   r   r   r   r   r   r     r   zOTTableWriter.__setitem__c                 C   
   | j | S r$   r   r   r   r   r   r     r(   zOTTableWriter.__getitem__c                 C   s   | j |= d S r$   r   r   r   r   r   __delitem__     zOTTableWriter.__delitem__c                 C   sL   d}| j D ]}t|dr||j7 }qt|dr||j7 }q|t| }q|S )z<Return the length of this table in bytes, without subtables.r   getCountDatar   )r   r^   sizer   r   )r   litemr   r   r   getDataLength  s   


zOTTableWriter.getDataLengthc              	   C   s   t | j}| j}t|}t|D ]T}|| }t|drd|jdkr+t|jj| ||< q|jdkrOzt	|jj| ||< W q t
jyN   | |j}t|w |jdkr_t|jj| ||< qt|jqt|S )z;Assemble the data for this writer/table, without subtables.r   r   r   r   )listr   rk   r   r   r^   r   	packULongr   
packUShortr{   errorgetOverflowErrorRecordr"   
packUInt24rR   r   )r   r   rk   numItemsrh   r   r'   r   r   r   getData  s,   





zOTTableWriter.getDatac                 C   sb   t | j}tttd}t|D ]\}}t|dr,|j|v r'||j d||< qt|jq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   	enumerater^   r   rR   r   )r   r   Z	packFuncsrh   r   r   r   r   getDataForHarfbuzz  s   



z OTTableWriter.getDataForHarfbuzzc                 C   r)   r$   )r   r   r   r   r   r   r     s   
zOTTableWriter.__hash__c                 C      |  |}|tu r|S | S r$   r   r   r   ru   resultr   r   r   __ne__     
zOTTableWriter.__ne__c                 C       t | t |kr
tS | j|jkS r$   )rU   r   r   rt   r   r   r   r        zOTTableWriter.__eq__Fc                 C   s   t | d}t | d}|r|si }| j}tt|D ],}|| }t |dr+| ||< qt |drE|jj||d |sE||j|j|| _qt|| _d S )N	Extension	DontSharer   r   shareExtension)	r^   r   r   r   r   r   _doneWriting
setdefaulttuple)r   internedTablesr   isExtensionZ	dontSharer   rh   r   r   r   r   r     s&   



	
zOTTableWriter._doneWritingc                 C   s8  d|t | < t| j}tt|}|  t| d}|}|r.|d us&J d|d i }}}d}t| drdt|D ]}	| j|	 }
t|
drRt|
jdd dkrRd} nq9t |
j|vrc|
j	||| n	 |D ].}	| j|	 }
t|
dssqf|r|	d	krt|
jdd dkrqft |
j|vr|
j	||| qf	 qf|
|  d S )
NTr   zUProgram or XML editing error. Extension subtables cannot contain extensions subtablesFsortCoverageLastr   ra   Coverager   )idr   r   r   r   reverser^   r8   r   _gatherTablesappend)r   tables	extTablesdoner   ZiRanger   Z
selfTablesr   rh   r   r   r   r   r   
  sJ   	






zOTTableWriter._gatherTablesc                 C   s  g }g }|}|D ]
}	| dd|	f qd}
d}t| drOt| jD ]-\}}t|dd dkrNd}
t||vrA|||||| }}n|t| }| |  nq!d}d}t| jD ]I\}}t|drd|}nt|dro||j7 }qX|t| }qXt|j	|vr|j	||||| }}n|t|j	 }||j
|f}| | ||j
7 }qX| |  | ||f |d	7 }||t| < |
r|  |S )
Nr   Fr   ra   r   Tr   r   r   )r   r^   r   r   r8   r   _gatherGraphForHarfbuzzr   r   r   r   pop)r   r   obj_listr   objidxvirtual_edgesZ
real_linksZvirtual_linksZitem_idxidxr   Zcoverage_idxrh   r   Z	child_idxZ
offset_posrk   Z	real_edger   r   r   r   J  sX   










z%OTTableWriter._gatherGraphForHarfbuzzc                 C   s   i }| j |dd g }g }i }d}g }| ||||| d}|D ]}	||	_||	  }q g }
|D ]}	|	 }|
| q0ttdrJtt	||
|S t
|
|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
        Tr   r   repack_with_tag)r   r   rk   r   r   r   r^   rT   r   r   r   )r   r5   r   r   r   r   r   r   rk   r9   r;   	tableDatar   r   r   rQ     s&   
z%OTTableWriter.getAllDataUsingHarfbuzzTc           
      C   s   |r	i }|  | g }g }i }| ||| |  |  d}|D ]}||_||  }q"|D ]}||_||  }q0g }|D ]}| }	||	 q@|D ]}| }	||	 qNt|S )z+Assemble all data, including all subtables.r   )r   r   r   rk   r   r   r   r   )
r   rP   r   r   r   r   rk   r9   r;   r   r   r   r   rV     s0   
zOTTableWriter.getAllDatac                 C   s   |  | j| j}| |_|S r$   )rs   rl   r5   r   )r   Z	subwriterr   r   r   getSubWriter  s   zOTTableWriter.getSubWriterc                 C   s   | j td| | d S rx   r   r   r{   pack)r   r}   r&   r   r   r   
writeValue  s   zOTTableWriter.writeValuec                 C   s2   t  ||}tjdkr|  | j|  d S r   )r   r   r   r   r   r   tobytes)r   r}   valuesar   r   r   
writeArray  s   
zOTTableWriter.writeArrayc                 C   <   d|  krdk sJ | J || j td| d S )Ni   z>br   r   r&   r   r   r   	writeInt8     $zOTTableWriter.writeInt8c                 C      |  d| d S )Nr   r   r   r   r   r   r   writeInt8Array  r   zOTTableWriter.writeInt8Arrayc                 C   r   )Ni    z>hr   r  r   r   r   
writeShort  r  zOTTableWriter.writeShortc                 C   r  )Nr   r  r  r   r   r   writeShortArray  r   zOTTableWriter.writeShortArrayc                 C      | j td| d S )Nz>ir   r  r   r   r   	writeLong     zOTTableWriter.writeLongc                 C   r  )Nrh   r  r  r   r   r   writeLongArray  r   zOTTableWriter.writeLongArrayc                 C   r   )Nr      >Br   r  r   r   r   
writeUInt8  r  zOTTableWriter.writeUInt8c                 C   r  )Nr   r  r  r   r   r   writeUInt8Array  r   zOTTableWriter.writeUInt8Arrayc                 C   r   )Nr   i   >Hr   r  r   r   r   writeUShort  r  zOTTableWriter.writeUShortc                 C   r  )Nr   r  r  r   r   r   writeUShortArray  r   zOTTableWriter.writeUShortArrayc                 C   r  )N>Ir   r  r   r   r   
writeULong  r  zOTTableWriter.writeULongc                 C   r  )Nr   r  r  r   r   r   writeULongArray  r   zOTTableWriter.writeULongArrayc                 C   sH   d|  krdk sJ | J |t d|}| j|dd   d S )Nr      z>Lr   r{   r   r   r   )r   r&   r   r   r   r   writeUInt24  s   $zOTTableWriter.writeUInt24c                 C   s   |D ]}|  | qd S r$   )r  )r   r   r&   r   r   r   writeUInt24Array  s   zOTTableWriter.writeUInt24Arrayc                 C   s0   t | }t|dksJ || j| d S r   )r   r   r   r   r   )r   tagr   r   r   writeTag  s   zOTTableWriter.writeTagc                 C   s   | j t|| d S r$   )r   r   r   r   r   r   r   writeSubTable  r   zOTTableWriter.writeSubTabler   c                 C   s    t ||||d}| j| |S )N)r   r&   )CountReferencer   r   )r   r9   ra   r   r&   refr   r   r   writeCountReference  s   z!OTTableWriter.writeCountReferencec                 C   s    t j|f|  }| j| d S r$   r  )r   formatr   r;   r   r   r   writeStruct  s   zOTTableWriter.writeStructc                 C   s   | j | d S r$   )r   r   )r   r;   r   r   r   	writeData  r   zOTTableWriter.writeDatac                 C   s  d  } } }}| j dkr|j}nr| j dkr| j}|j}nft|dd}t|dr+|j}| j dkr8| jj}| j}nK| j dkrG| jjj}| jj}n<d| j |g}| j}|rk|j d	vrkd|j |g}|j}|rk|j d	vsY|r|j dkr||jjj}|jj}n|jj}|j}t| j||||fS )
NZ
LookupListZLookupra   z<none>repeatIndexSubTableExtSubTable.)r(  r'  )ra   r&  r8   r^   r   joinr   r5   )r   r   r   r   r   r   Zp1r   r   r   r     s<   









z$OTTableWriter.getOverflowErrorRecordNNFrf   )r   N)*r   r    r!   rg   r   r   r   r   r   r   r   r   r   r   r   r   r   rQ   rV   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   rD     sP    

(@9
!#

rD   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 ur| | d S d S r$   )r9   ra   r   setValue)r   r9   ra   r   r&   r   r   r   r   F  s   zCountReference.__init__c                 C   sF   | j }| j}|| d u r|||< d S || |ks!J ||| |fd S r$   r9   ra   )r   r&   r9   ra   r   r   r   r-  M  s
   "zCountReference.setValuec                 C   s   | j | j S r$   r.  r   r   r   r   getValueU  r   zCountReference.getValuec                 C   s.   | j | j }|d u rd}tttd| j |S )Nr   )r   r   r   )r9   ra   	packUInt8r   r   r   )r   vr   r   r   r   X  s   zCountReference.getCountDatar+  )r   r    r!   rg   r   r-  r/  r   r   r   r   r   r   C  s    
r   c                 C      t d| S )Nr  r{   r   r%   r   r   r   r0  _  r   r0  c                 C   r2  )Nr  r3  r%   r   r   r   r   c  r   r   c                 C   s0   d|   krdk sJ |  J | t d| S )Nr   l        r  r3  r%   r   r   r   r   g  s   $r   c                 C   s8   d|   krdk sJ |  J | t d| dd  S )Nr   r  r  r   r3  r%   r   r   r   r   l  s   $r   c                   @   s   e Zd ZdZdd Zd+ddZ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d&ee fd'd(Zd)d* ZdS ).	BaseTablez0Generic base class for all OpenType (sub)tables.c                 C   s<   | j d}|r| `| j}| `| || t| |S t|Nr=   )__dict__getr=   r<   r:   r8   AttributeError)r   attrr=   r<   r   r   r   __getattr__t  s   
zBaseTable.__getattr__Fc                 C   sP   | j d}|r| `| j}| `| || |r$|  D ]
}|j| qd S d S r5  )r6  r7  r=   r<   r:   iterSubTablesr&   re   )r   rd   r=   r<   Zsubtabler   r   r   re     s   zBaseTable.ensureDecompiledc                 C   s0   d| j v r| j  }| j d  |d< |S | j S r5  )r6  rv   )r   rJ   r   r   r   __getstate__  s
   

zBaseTable.__getstate__c                 C   sh   d}| j D ],}||}|tu rt  S d}|jr+|j|v r'||j |j }nt  S ||| 7 }q|S )Nr   r   )
convertersgetRecordSizer   repeataux)clsr=   Z	totalSizeconvr   
countValuer   r   r   r>    s   


zBaseTable.getRecordSizec                 C   s   | j S r$   )r=  r   r   r   r   getConverters  s   zBaseTable.getConvertersc                 C   r   r$   )convertersByNamer   r   r   r   getConverterByName  r(   zBaseTable.getConverterByNameNc              	   C   s   |   D ]q}|jrIt| |jst| |jg  tt| |j|j }z| |j}t| |j| W q t	yH   |rF|j|v rF||j 
| Y qw |jrUt|jd | jsUqt| |jr\qt|drht| |jd  t|drut| |j|j qd S )NZwriteNullOffsetDEFAULT)rD  r?  r^   ra   setattrr   r8   r@  rF  KeyErrorr-  evalr6  rG  )r   Z
propagatorrB  rC  Z
count_convr   r   r   r`     s.   

zBaseTable.populateDefaultsc                 C   s  |  | i }|| _|  D ]}|jdkr||j|d }|jdkr,||j|d }|jdkr8||d }|jdkrF||j|d }zQ|jrut|jtrT|j}n|j|v r_||j }n||j }||j	7 }|
||||||j< n!|j	rt|j	d |sW q||||||j< |jr||j ||j< W q ty } z|j}|j|f |_ d }~ww t| d	r| || | `d S | j| | `d S )
Nr'  
LookupTyper(  ZExtensionLookupTypeZFeatureParamsZ
FeatureTagZ	SubStructZ	MorphTypepostRead)
readFormatZ_BaseTable__rawTablerD  ra   ZgetConverterr5   r?  
isinstanceintr@  r   rJ  readisPropagated	Exceptionargsr^   rL  r6  update)r   r=   r<   r9   rB  rC  rN   ra   r   r   r   r:     sL   








zBaseTable.decompilec                 C   s  |    t| drt| d }| |}|ot| d}nd}| j }|  D ]}|jr?|jr?||j	}t
|tr?|||j	< q't| drHd|_t| drPd|_t| jdr_|d | jj | | |  D ] }||j	}|jr|d u rzg }t||j }t
|jtrt||jksJ d	|jt|f n|j|v rt||j|d
 n||j | z
||||| W qh ty } z|j|j	d f |_ d }~ww |jrt
|tr|}	|j|	_||	 |	 ||j	< n|||j	|j}	d ||j	< |jr|	||j	< qh|jr'|j	|vrd ||j	< |||j	|j||j	 }	|	|d< qh|jr4t|jd |s4qhz
| |||| W n! ty_ } z|d urP|jj!n|j	}
|j|
f |_ d }~ww |jri|||j	< qh|rq| `"d S d S )NpreWriteFormatFr   r   r   TrK  zexpected %d values, got %dr%   z[])#re   r^   rU  r6  rv   rD  ZisCountrQ  r7  ra   rN  r   r   r   rs   r-  rK  writeFormatr?  r   r@  rO  r   rR  rS  r~   r   r%  r/  r"  ZisLookupTyperJ  writer   rV  )r   rM   r<   ZdeleteFormatr9   rB  r&   rC  rN   r!  ra   r   r   r   rE     s   

















zBaseTable.compilec                 C      d S r$   r   r   r=   r   r   r   rM  S     zBaseTable.readFormatc                 C   rY  r$   r   rW   r   r   r   rW  V  r[  zBaseTable.writeFormatc                 C   sl   |r|n| j j}|d u rg }t| dr|d| jfg }||| |  | || || |  d S )NrV  )rs   r   r^   rV  begintagnewliner[   endtag)r   	xmlWriterr<   rb   ra   Z	tableNamer   r   r   r\   Y  s   

zBaseTable.toXMLc              
   C   s   |   D ]E}|jr+t| |jg }tt|D ]}|| }|||||jd|fg qq|jr8t|jd t	| s8qt| |jd }|||||jg  qd S )Nindex)
rD  r?  r8   ra   r   r   ZxmlWriter@  rJ  vars)r   r_  r<   rB  r&   rh   r   r   r   r   r[   e  s   zBaseTable.toXML2c                 C   s   z|  |}W n ty    w ||||}|jd ur7t| |jd }|d u r0g }t| |j| || d S t| |j| d S r$   )rF  rI  ZxmlReadr?  r8   ra   rH  r   )r   ra   rb   rc   r<   rB  r&   seqr   r   r   r_   w  s   
zBaseTable.fromXMLc                 C   r   r$   r   r   r   r   r   r     r   zBaseTable.__ne__c                 C   s0   t | t |kr
tS |   |  | j|jkS r$   )rU   r   re   r6  rt   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()ra   r4  r&   Nr`  )	r   r    r!   rg   r   __annotations__r`  r   rO  r   r   r   r   SubTableEntry  s
   
 rd  returnc                 #   sr      D ]1}|j t d}|du rqt|tr" |V  qt|tr6 fddt|D E dH  qdS )a7  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)rN  r4  rd  )r   rh   r1  ra   r   r   r   	<genexpr>  s    
z*BaseTable.iterSubTables.<locals>.<genexpr>)rD  ra   r8   rN  r4  rd  r   r   )r   rB  r&   r   rf  r   r;    s   

zBaseTable.iterSubTablesc                 C   r)   r$   )getVariableAttrsrs   r   r   r   r   rh    r(   zBaseTable.getVariableAttrsr,  r$   r+  )r   r    r!   rg   r:  re   r<  classmethodr>  rD  rF  r`   r:   rE   rM  rW  r\   r[   r_   r   r   r
   rd  r	   r;  rh  r   r   r   r   r4  q  s,    
	

*e
	r4  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 )FormatSwitchingBaseTablezvMinor specialization of BaseTable, for tables that have multiple
    formats, eg. CoverageFormat1 vs. CoverageFormat2.c                 C   s   t S r$   )r   )rA  r=   r   r   r   r>    s   z&FormatSwitchingBaseTable.getRecordSizec                 C   s2   z| j }W n ty   g  Y S w | j| j g S r$   )rV  r8  r=  r7  )r   fmtr   r   r   rD    s   
z&FormatSwitchingBaseTable.getConvertersc                 C   s   | j | j | S r$   )rE  rV  r   r   r   r   rF    r   z+FormatSwitchingBaseTable.getConverterByNamec                 C      |  | _d S r$   )r   rV  rZ  r   r   r   rM    r   z#FormatSwitchingBaseTable.readFormatc                 C      | | j d S r$   )r  rV  rW   r   r   r   rW    r   z$FormatSwitchingBaseTable.writeFormatNc                 C   s   t | |||| d S r$   )r4  r\   )r   r_  r<   rb   ra   r   r   r   r\     r   zFormatSwitchingBaseTable.toXMLc                 C   s   t | j| jS r$   )rh  rs   rV  r   r   r   r   rh    r   z)FormatSwitchingBaseTable.getVariableAttrsr+  )r   r    r!   rg   ri  r>  rD  rF  rM  rW  r\   rh  r   r   r   r   rj    s    

rj  c                   @   r   )UInt8FormatSwitchingBaseTablec                 C   rl  r$   )r   rV  rZ  r   r   r   rM    r   z(UInt8FormatSwitchingBaseTable.readFormatc                 C   rm  r$   )r  rV  rW   r   r   r   rW    r   z)UInt8FormatSwitchingBaseTable.writeFormatN)r   r    r!   rM  rW  r   r   r   r   rn    r,   rn  )Zuint16Zuint8c                 C   s(   zt |  W S  ty   td| w )NzUnsupported format type: )formatSwitchingBaseTablesrI  	TypeError)Z
formatTyper   r   r    getFormatSwitchingBaseTableClass  s
   
rq  rA  rk  re  c                 C   s   t | ts	t| t | tr |du rtd| j | j| }n| j}d|vr)dS i }| D ]\}}| }|dur?|||< q/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)
issubclassr4  rp  rj  r   rE  r   ZgetVarIndexOffsetr   sortedr   )rA  rk  r=  ZvarAttrsra   rB  rj   r   r   r   rh    s    

rh  ))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   )r  Z	Reserved8r   r   c                  C   s(   i } t D ]\}}}}|||f| |< q| S r$   )valueRecordFormat)dmaskra   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   s8   g }t D ]\}}}}||@ r||||f q|| _d S r$   )ry  r   r#  )r   valueFormatr#  r{  ra   r|  r}  r   r   r   r   :  s   
zValueRecordFactory.__init__c                 C   r)   r$   )r   r#  r   r   r   r   __len__A  r(   zValueRecordFactory.__len__c                 C   s   | j }|sd S t }|D ]4\}}}|r| }n| }|r:|r8ddlm}	 ||}
t|	| }||
| nd }t	||| q|S Nr   r2   )
r#  ValueRecordr   r   r6   r3   rw   r8   r:   rH  )r   r=   r<   r#  valueRecordra   r|  r}  r&   r3   Z	subReaderr   r   r   readValueRecordD  s"   

z"ValueRecordFactory.readValueRecordc           	      C   st   | j D ]4\}}}t||d}|r*|r$| }|j|dd ||| q|d q|r2|| q|| qd S )Nr   r   )r   )r#  r8   r   r  rE   r  r	  )	r   rM   r<   r  ra   r|  r}  r&   r   r   r   r   writeValueRecordZ  s   z#ValueRecordFactory.writeValueRecordN)r   r    r!   rg   r   r  r  r  r   r   r   r   r  7  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 ur9t D ]\}}}}||@ rt| ||rd nd q|d ur5|j D ]\}}t| |s.q$t| || q$d S d S |d urE|j | _d S d S Nr   )ry  rH  r6  r   r^   rv   )	r   r  srcr{  ra   r|  r}  rr  valr   r   r   r   m  s   
zValueRecord.__init__c                 C   s(   d}| j  D ]
}|t| d B }q|S r  )r6  keysvalueRecordFormatDict)r   r#  ra   r   r   r   	getFormatz  s   zValueRecord.getFormatc                 C   s0   d}| j  D ]\}}|r|t| d B }q|S r  )r6  r   r  )r   r#  ra   r&   r   r   r   getEffectiveFormat  s   zValueRecord.getEffectiveFormatc                 C   s  |d u rg }nt |}td d D ]\}}}}	t| |r&||t| |f qg }
tdd D ]\}}}}	t| |rJt| |}|d urJ|
||f q/|
ru||| |  |
D ]\}}|d uri|j|||d qY|| |  d S |	|| |  d S )Nr   ru  )ra   )
r   ry  r^   r   r8   r\  r]  r\   r^  Z	simpletag)r   r_  r<   Z	valueNamerb   ZsimpleItemsr{  ra   r|  r#  ZdeviceItemsZdeviceZdeviceRecordr   r   r   r\     s2   



zValueRecord.toXMLc                 C   s   ddl m} | D ]\}}t| |t| q
|D ]1}t|ts!q|\}}}t|| }	|D ]}
t|
ts6q.|
\}}}|	|||| q.t| ||	 qd S r  )	r6   r3   r   rH  rO  rN  r   r8   r_   )r   ra   rb   rc   r<   r3   kr1  elementr&   Zelem2Zname2Zattrs2Zcontent2r   r   r   r_     s   



zValueRecord.fromXMLc                 C   r   r$   r   r   r   r   r   r     r   zValueRecord.__ne__c                 C   r   r$   )rU   r   r6  rt   r   r   r   r     r   zValueRecord.__eq__r+  r$   )
r   r    r!   r   r  r  r\   r_   r   r   r   r   r   r   r  j  s    

r  r$   );ZfontTools.configr   ZfontTools.misc.textToolsr   r   r   enumr   r   r   r{   Zlogging	functoolsr   typingr	   r
   r   r   Z	getLoggerr   r@   rB   Z	uharfbuzzrT   callabler8   rC   r?   objectr   rR  r"   r-   r1   r   r   itemsizer7   r   rD   r   r0  r   r   r   r4  rj  rn  ro  rq  rO  r   rh  ry  r~  r  r  r  r   r   r   r   <module>   sj    
 1t   >  L$	"!3