U
    »mœd0Y  ã                
   @   s€  d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
mZ ddlZddlmZ ddlZe e¡ZG d	d
„ d
eƒZdZdZddddddddddœ	Zefdd„ZG dd„ deƒZdZe e¡ZdZe e¡ZdZe e¡Z dZ!e e!¡Z"dZ#e e#¡Z$G d d!„ d!eƒZ%G d"d#„ d#e%ƒZ&G d$d%„ d%e%ƒZ'G d&d'„ d'ƒZ(d(d)„ Z)d*d+„ Z*d,d-„ Z+ed.k�r|ddl,Z,ddl-Z-e, .e- /¡ j0¡ dS )/a¬  ttLib/sfnt.py -- low-level module to deal with the sfnt file format.

Defines two public classes:
	SFNTReader
	SFNTWriter

(Normally you don't have to use these classes explicitly; they are
used automatically by ttLib.TTFont.)

The reading and writing of sfnt files is separated in two distinct
classes, since whenever the number of tables changes or whenever
a table's length changes you need to rewrite the whole file anyway.
é    )ÚBytesIO)ÚSimpleNamespace)ÚTag)Ússtruct)Ú
TTLibErrorÚTTLibFileIsCollectionErrorN)ÚOrderedDictc                   @   sZ   e Zd Zdd„ Zddd„Zdd„ ZeZd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )Ú
SFNTReaderc                 O   s^   |rT| t krT|d }| d¡ t| d¡ƒ}| d¡ |dkrTddlm} t |¡S t | ¡S )zmReturn an instance of the SFNTReader sub-class which is compatible
        with the input file type.
        r   é   ZwOF2)ÚWOFF2Reader)r	   Úseekr   ÚreadÚfontTools.ttLib.woff2r   ÚobjectÚ__new__)ÚclsÚargsÚkwargsÚinfileÚsfntVersionr   © r   úM/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/fontTools/ttLib/sfnt.pyr      s    


zSFNTReader.__new__r   éÿÿÿÿc                 C   sÖ  || _ || _d | _d | _t| _| j  d¡ | j  d¡| _| j  d¡ | jdkrÌt	| j ƒ}|j
}d|  krr|k s„n td|d  ƒ‚|| _
| j  |j| ¡ | j  t¡}t|ƒtkr¼tdƒ‚t t|| ¡ nz| jdk�rd| _t| _| j  t¡}t|ƒtk�rtd	ƒ‚t t|| ¡ n0| j  t¡}t|ƒtk�r8td
ƒ‚t t|| ¡ t| jƒ| _| jdk�rftdƒ‚i }t| jƒD ],}|  ¡ }	|	 | j ¡ t|	jƒ}
|	||
< �qttt| ¡ dd„ d�ƒ| _| jdk�rÒt| ƒ| _d S )Nr   r
   s   ttcfz2specify a font number between 0 and %d (inclusive)é   ú'Not a Font Collection (not enough data)ó   wOFFÚwoffz!Not a WOFF font (not enough data)z1Not a TrueType or OpenType font (not enough data))ú   ZOTTOÚtruez1Not a TrueType or OpenType font (bad sfntVersion)c                 S   s
   | d j S )Nr   )Úoffset)Úir   r   r   Ú<lambda>\   ó    z%SFNTReader.__init__.<locals>.<lambda>)Úkey) ÚfileÚcheckChecksumsÚflavorÚ
flavorDataÚSFNTDirectoryEntryÚDirectoryEntryr   r   r   ÚreadTTCHeaderÚnumFontsr   ÚoffsetTableÚsfntDirectorySizeÚlenr   r   ÚunpackÚsfntDirectoryFormatÚWOFFDirectoryEntryÚwoffDirectorySizeÚwoffDirectoryFormatr   ÚrangeÚ	numTablesÚfromFileÚtagr   ÚsortedÚitemsÚtablesÚWOFFFlavorData)Úselfr$   r%   Z
fontNumberÚheaderr+   Údatar:   r    Úentryr7   r   r   r   Ú__init__.   s\    

ÿÿ
zSFNTReader.__init__c                 C   s
   || j kS ©N©r:   ©r<   r7   r   r   r   Úhas_keyb   s    zSFNTReader.has_keyc                 C   s
   | j  ¡ S rA   )r:   Úkeys©r<   r   r   r   rE   g   s    zSFNTReader.keysc                 C   sŽ   | j t|ƒ }| | j¡}| jrŠ|dkrJt|dd… d |dd…  ƒ}nt|ƒ}| jdkrt||jksŠtd| ƒ‚n||jkrŠt 	d|¡ |S )zFetch the raw table data.ÚheadNé   ó       é   r   zbad checksum for '%s' table)
r:   r   ÚloadDatar$   r%   ÚcalcChecksumÚcheckSumÚAssertionErrorÚlogÚwarning)r<   r7   r?   r>   Úchecksumr   r   r   Ú__getitem__j   s    "

zSFNTReader.__getitem__c                 C   s   | j t|ƒ= d S rA   )r:   r   rC   r   r   r   Ú__delitem__|   s    zSFNTReader.__delitem__c                 C   s   | j  ¡  d S rA   )r$   ÚcloserF   r   r   r   rT      s    zSFNTReader.closec                 C   s@   t | jtƒr| jS | j ¡ }|d= | jj|d< | j ¡ |d< |S )Nr$   Ú	_filenameÚ_filepos)Ú
isinstancer$   r   Ú__dict__ÚcopyÚnameÚtell©r<   Ústater   r   r   Ú__getstate__ˆ   s    
zSFNTReader.__getstate__c                 C   s<   d|kr,t | d¡dƒ| _| j | d¡¡ | j |¡ d S )Nr$   rU   ÚrbrV   )ÚopenÚpopr$   r   rX   Úupdater\   r   r   r   Ú__setstate__”   s    zSFNTReader.__setstate__N)r   r   )Ú__name__Ú
__module__Ú__qualname__r   r@   rD   Ú__contains__rE   rR   rS   rT   r^   rc   r   r   r   r   r	      s   
4	r	   é   Fr   é   é   rH   é
   é   é   é2   éd   )	r   é   ri   r
   rj   rh   é   rH   é	   c                 C   sd   d|  krdks"n t d| ƒ‚tr.|dkrDddlm} || |ƒS ddlm} || t| d�S dS )aE  Compress 'data' to Zlib format. If 'USE_ZOPFLI' variable is True,
    zopfli is used instead of the zlib module.
    The compression 'level' must be between 0 and 9. 1 gives best speed,
    9 gives best compression (0 gives no compression at all).
    The default value is a compromise between speed and compression (6).
    r   rr   zBad compression level: %s)Úcompress)ZnumiterationsN)Ú
ValueErrorÚ
USE_ZOPFLIÚzlibrs   Zzopfli.zlibÚZOPFLI_LEVELS)r>   Úlevelrs   r   r   r   rs   ²   s    
rs   c                   @   sV   e Zd Zdd„ Zd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S )Ú
SFNTWriterc                 O   sb   d}|rd|kr|d }n|r2t |ƒdkr2|d }| tkrX|dkrXddlm} t |¡S t | ¡S )zpReturn an instance of the SFNTWriter sub-class which is compatible
        with the specified 'flavor'.
        Nr&   ri   Zwoff2r   )ÚWOFF2Writer)r.   ry   r   rz   r   r   )r   r   r   r&   rz   r   r   r   r   Æ   s    

zSFNTWriter.__new__r   Nc                 C   sø   || _ || _t|ƒ| _|| _|| _| jdkrTt| _t| _	t
| _d| _t|t  | _nH| jrhtd| j ƒ‚t| _t| _	t| _ddlm} ||dƒ\| _| _| _| j  ¡ | _| j| j	 || jj  | _| j  | j¡ | j  d| j| j  ¡   ¡ tƒ | _d S )Nr   ZwOFFúUnknown flavor '%s'r   ©ÚgetSearchRangeé   ó    ) r$   r5   r   r   r&   r'   r3   ÚdirectoryFormatr2   ÚdirectorySizer1   r)   Ú	signaturer-   ÚsfntDirectoryEntrySizeÚorigNextTableOffsetrN   r0   r(   ÚfontTools.ttLibr}   ÚsearchRangeÚentrySelectorÚ
rangeShiftr[   ÚdirectoryOffsetÚ
formatSizeÚnextTableOffsetr   Úwriter   r:   )r<   r$   r5   r   r&   r'   r}   r   r   r   r@   Ø   s>    


ÿ ÿÿ
þÿzSFNTWriter.__init__c                 C   s$   || j krtd| ƒ‚|| j |< d S )Núcannot rewrite '%s' table)r:   r   )r<   r7   r?   r   r   r   ÚsetEntry	  s    
zSFNTWriter.setEntryc                 C   sü   || j krtd| ƒ‚|  ¡ }||_| j|_|dkrdt|dd… d |dd…  ƒ|_|| _d|_	n
t|ƒ|_| 
| j|¡ | jdkr¦| j|_|  j|jd	 d
@ 7  _| j|jd	 d
@  | _| j d| j| j ¡   ¡ | j| j ¡ ksìt‚|  ||¡ dS )zWrite raw table data to disk.r�   rG   NrH   rI   rJ   Tr   ri   éüÿÿÿr   )r:   r   r)   r7   r‹   r   rL   rM   Ú	headTableÚuncompressedÚsaveDatar$   r&   r„   Ú
origOffsetÚ
origLengthÚlengthrŒ   r[   rN   rŽ   )r<   r7   r>   r?   r   r   r   Ú__setitem__  s$    
"

zSFNTWriter.__setitem__c                 C   s
   | j | S rA   rB   rC   r   r   r   rR   -  s    zSFNTWriter.__getitem__c           
      C   s€  t | j ¡ ƒ}t|ƒ| jkr2td| jt|ƒf ƒ‚| jdk�rìd| _d| _d| _	|  j	dt|ƒ 7  _	|D ] \}}|  j	|j
d d@ 7  _	qj| jr˜| jntƒ }|jd	k	rÄ|jd	k	rÄ|j| _|j| _n6t| d
ƒrît d| jdd… ¡\| _| _nd | _| _|j�rJt|jƒ| _| j dd¡ | j ¡ | _t|jƒ}t|ƒ| _| j |¡ nd | _ | _| _|j�rÄ| j dd¡ | j ¡ }|d d@ }| j d||  ¡ | j ¡ | _t|jƒ| _| j |j¡ nd | _| _| j dd¡ | j ¡ | _n| j�rt d| j ƒ‚t! "| j#| ¡}| j | j$| j% ¡ d}	|D ]$\}}|dk�rBd}	|| &¡  }�q,|	�rb|  '|¡ | j | j$¡ | j |¡ d	S )zTAll tables must have been written to disk. Now write the
        directory.
        z-wrong number of tables; expected %d, found %dr   r   r   rJ   r~   ri   r�   Nr�   z>HHr
   rH   rp   r   r{   rG   r   )(r8   r:   r9   r.   r5   r   r&   r‚   ÚreservedZtotalSfntSizer”   r'   r;   ÚmajorVersionÚminorVersionÚhasattrÚstructr/   r�   ÚmetaDataÚmetaOrigLengthr$   r   r[   Ú
metaOffsetrs   Ú
metaLengthrŒ   ÚprivDataÚ
privOffsetÚ
privLengthr•   rN   r   Úpackr€   r‰   r�   ÚtoStringÚwriteMasterChecksum)
r<   r:   r7   r?   r>   ZcompressedMetaDataÚoffZ	paddedOffÚ	directoryZseenHeadr   r   r   rT   0  sn    ÿÿ

 ÿ




zSFNTWriter.closec                 C   s  t | j ¡ ƒ}g }tt|ƒƒD ]}| | j||  j¡ q| jtkrÂddl	m
} || jdƒ\| _| _| _t t| ¡}t| j ¡ ƒ}|D ]:\}}tƒ }	|j|	_|j|	_|j|	_|j|	_||	 ¡  }q†tt| jƒt  }
|
t|ƒksät‚| t|ƒ¡ t|ƒd@ }d| d@ }|S )Nr   r|   r~   ì   ÿÿ l   º/ac )Úlistr:   rE   r4   r.   ÚappendrM   r)   r(   r…   r}   r5   r†   r‡   rˆ   r   r£   r0   r8   r9   r7   r“   r   r”   r•   r¤   r-   rƒ   rN   rL   Úsum)r<   r§   ÚtagsZ	checksumsr    r}   r:   r7   r?   Z	sfntEntryZdirectory_endrQ   Úchecksumadjustmentr   r   r   Ú_calcMasterChecksumw  s2    
 ÿzSFNTWriter._calcMasterChecksumc                 C   s:   |   |¡}| j | jd jd ¡ | j t d|¡¡ d S )NrG   rH   z>L)r®   r$   r   r:   r   rŒ   r›   r£   )r<   r§   r­   r   r   r   r¥   ˜  s    
zSFNTWriter.writeMasterChecksumc                 C   s   dS ©NFr   rF   r   r   r   ÚreordersTablesž  s    zSFNTWriter.reordersTables)r   NN)rd   re   rf   r   r@   rŽ   r–   rR   rT   r®   r¥   r°   r   r   r   r   ry   Å   s      ú
1G!ry   a  
		> # big endian
		TTCTag:                  4s # "ttcf"
		Version:                 L  # 0x00010000 or 0x00020000
		numFonts:                L  # number of fonts
		# OffsetTable[numFonts]: L  # array with offsets from beginning of file
		# ulDsigTag:             L  # version 2.0 only
		# ulDsigLength:          L  # version 2.0 only
		# ulDsigOffset:          L  # version 2.0 only
zä
		> # big endian
		sfntVersion:    4s
		numTables:      H    # number of tables
		searchRange:    H    # (max2 <= numTables)*16
		entrySelector:  H    # log2(max2 <= numTables)
		rangeShift:     H    # numTables*16-searchRange
zc
		> # big endian
		tag:            4s
		checkSum:       L
		offset:         L
		length:         L
ab  
		> # big endian
		signature:      4s   # "wOFF"
		sfntVersion:    4s
		length:         L    # total woff file size
		numTables:      H    # number of tables
		reserved:       H    # set to 0
		totalSfntSize:  L    # uncompressed size
		majorVersion:   H    # major version of WOFF file
		minorVersion:   H    # minor version of WOFF file
		metaOffset:     L    # offset to metadata block
		metaLength:     L    # length of compressed metadata
		metaOrigLength: L    # length of uncompressed metadata
		privOffset:     L    # offset to private data block
		privLength:     L    # length of private data block
zº
		> # big endian
		tag:            4s
		offset:         L
		length:         L    # compressed length
		origLength:     L    # original length
		checkSum:       L    # original checksum
c                   @   sT   e 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„ Z
dd„ ZdS )r)   c                 C   s
   d| _ d S r¯   )r‘   rF   r   r   r   r@   æ  s    zDirectoryEntry.__init__c                 C   s   t  | j| | j¡| ¡ d S rA   )r   r/   Úformatr   rŠ   )r<   r$   r   r   r   r6   é  s    zDirectoryEntry.fromFilec                 C   s   t  | j|| ¡ d S rA   )r   r/   r±   )r<   Ústrr   r   r   Ú
fromStringì  s    zDirectoryEntry.fromStringc                 C   s   t  | j| ¡S rA   )r   r£   r±   rF   r   r   r   r¤   ï  s    zDirectoryEntry.toStringc                 C   s:   t | dƒr"d| jj| jt| ƒf S d| jjt| ƒf S d S )Nr7   z<%s '%s' at %x>z
<%s at %x>)rš   Ú	__class__rd   r7   ÚidrF   r   r   r   Ú__repr__ò  s    
zDirectoryEntry.__repr__c                 C   sD   |  | j¡ | | j¡}t|ƒ| jks*t‚t| jdƒr@|  |¡}|S )NÚ
decodeData)	r   r   r   r•   r.   rN   rš   r´   r·   ©r<   r$   r>   r   r   r   rK   ø  s    
zDirectoryEntry.loadDatac                 C   s:   t | jdƒr|  |¡}t|ƒ| _| | j¡ | |¡ d S )NÚ
encodeData)rš   r´   r¹   r.   r•   r   r   rŒ   r¸   r   r   r   r’      s
    

zDirectoryEntry.saveDatac                 C   s   |S rA   r   )r<   ÚrawDatar   r   r   r·     s    zDirectoryEntry.decodeDatac                 C   s   |S rA   r   )r<   r>   r   r   r   r¹   
  s    zDirectoryEntry.encodeDataN)rd   re   rf   r@   r6   r³   r¤   r¶   rK   r’   r·   r¹   r   r   r   r   r)   å  s   r)   c                   @   s   e Zd ZeZeZdS )r(   N)rd   re   rf   ÚsfntDirectoryEntryFormatr±   rƒ   rŠ   r   r   r   r   r(     s   r(   c                       s4   e Zd ZeZeZ‡ fdd„Zdd„ Zdd„ Z	‡  Z
S )r1   c                    s"   t t| ƒ ¡  ttdƒst| _d S )NÚzlibCompressionLevel)Úsuperr1   r@   rš   ÚZLIB_COMPRESSION_LEVELr¼   rF   ©r´   r   r   r@     s    
zWOFFDirectoryEntry.__init__c                 C   sJ   dd l }| j| jkr|}n,| j| jk s*t‚| |¡}t|ƒ| jksFt‚|S ©Nr   )rv   r•   r”   rN   Ú
decompressr.   )r<   rº   rv   r>   r   r   r   r·   $  s    
zWOFFDirectoryEntry.decodeDatac                 C   sP   t |ƒ| _| jst|| jƒ}| js0t |ƒ| jkr>|}| j| _n|}t |ƒ| _|S rA   )r.   r”   r‘   rs   r¼   r•   )r<   r>   ZcompressedDatarº   r   r   r   r¹   /  s    


zWOFFDirectoryEntry.encodeData)rd   re   rf   ÚwoffDirectoryEntryFormatr±   ÚwoffDirectoryEntrySizerŠ   r@   r·   r¹   Ú__classcell__r   r   r¿   r   r1     s
   r1   c                   @   s"   e Zd ZdZddd„Zdd„ ZdS )r;   r   Nc                 C   sÀ   d | _ d | _d | _d | _|r¼|j | _ |j| _|jr‚|j |j¡ |j |j¡}t	|ƒ|jks`t
‚|  |¡}t	|ƒ|jks|t
‚|| _|jr¼|j |j¡ |j |j¡}t	|ƒ|jks¶t
‚|| _d S rA   )r˜   r™   rœ   r    rŸ   r$   r   rž   r   r.   rN   Ú_decompressr�   r¢   r¡   )r<   Úreaderrº   r>   r   r   r   r@   A  s&    
zWOFFFlavorData.__init__c                 C   s   dd l }| |¡S rÀ   )rv   rÁ   )r<   rº   rv   r   r   r   rÅ   V  s    zWOFFFlavorData._decompress)N)rd   re   rf   ZFlavorr@   rÅ   r   r   r   r   r;   =  s   
r;   c                 C   sŠ   t | ƒd }|r | dd|  7 } d}d}|d dks8t‚tdt | ƒ|ƒD ]<}| ||| … }t dt |ƒd  |¡}|t|ƒ d@ }qH|S )a,  Calculate the checksum for an arbitrary block of data.

    If the data length is not a multiple of four, it assumes
    it is to be padded with null byte.

            >>> print(calcChecksum(b"abcd"))
            1633837924
            >>> print(calcChecksum(b"abcdxyz"))
            3655064932
    r
   r   r   i   ú>%dLr¨   )r.   rN   r4   r›   r/   r«   )r>   Ú	remainderÚvalueZ	blockSizer    ÚblockZlongsr   r   r   rL   \  s    rL   c                 C   sž   |   d¡ |  t¡}t|ƒtkr(tdƒ‚tƒ }t t||¡ |j	dkrNtdƒ‚|j
dksp|j
dksptd|j
 ƒ‚t d|j |  |jd	 ¡¡|_|j
dkrš|S )
Nr   r   ÚttcfzNot a Font Collectioné   i   zunrecognized TTC version 0x%08xrÇ   r
   )r   r   ÚttcHeaderSizer.   r   r   r   r/   ÚttcHeaderFormatÚTTCTagÚVersionrN   r›   r+   r,   )r$   r>   r<   r   r   r   r*   t  s"    


ÿ ÿ
r*   c                 C   sd   t ƒ }d|_d|_||_|  d¡ |  t t|¡¡ |  	¡ }|  t
jd|j fdg|j žŽ ¡ |S )NrË   rÌ   r   rÇ   )r   rÏ   rÐ   r+   r   rŒ   r   r£   rÎ   r[   r›   )r$   r+   r<   r   r   r   r   ÚwriteTTCHeaderˆ  s    
$rÑ   Ú__main__)1Ú__doc__Úior   Útypesr   ZfontTools.misc.textToolsr   ZfontTools.miscr   r…   r   r   r›   Úcollectionsr   ÚloggingÚ	getLoggerrd   rO   r   r	   r¾   ru   rw   rs   ry   rÎ   ÚcalcsizerÍ   r0   r-   r»   rƒ   r3   r2   rÂ   rÃ   r)   r(   r1   r;   rL   r*   rÑ   ÚsysÚdoctestÚexitÚtestmodÚfailedr   r   r   r   Ú<module>   s^   
 ö `
	


	
))
