a
    ZXh0Y                  
   @   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 u 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   Y/var/www/viveiro_mudafortebrasil/venv/lib/python3.9/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rt	| j }|j
}d|  krr|k sn td|d  || _
| j |j|  | j t}t|tkrt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vrftdi }t| jD ],}|  }	|	| j  t|	j}
|	||
< qttt| dd d| _| jdkrt| | _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 v S Nr:   r<   r7   r   r   r   has_keyc   s    zSFNTReader.has_keyc                 C   s
   | j  S rA   )r:   keysr<   r   r   r   rE   h   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sJ d| n||jkrtd| |S )zFetch the raw table data.headN             r   zbad checksum for '%s' table)	r:   r   loadDatar$   r%   calcChecksumcheckSumlogwarning)r<   r7   r?   r>   checksumr   r   r   __getitem__k   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   rS      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|vr,t |dd| _| j|d | j| d S )Nr$   rT   rbrU   )openpopr$   r   rW   updater[   r   r   r   __setstate__   s    zSFNTReader.__setstate__N)r   r   )__name__
__module____qualname__r   r@   rD   __contains__rE   rQ   rR   rS   r]   rb   r   r   r   r   r	      s   
4	r	      Fr         rH   
         2   d   )	r      rh   r
   ri   rg      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   rq   zBad compression level: %s)compress)ZnumiterationsN)
ValueError
USE_ZOPFLIzlibrr   Zzopfli.zlibZOPFLI_LEVELS)r>   levelrr   r   r   r   rr      s    
rr   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|v r|d }n|r2t |dkr2|d }| tu 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&   rh   Zwoff2r   )WOFF2Writer)r.   rx   r   ry   r   r   )r   r   r   r&   ry   r   r   r   r      s    

zSFNTWriter.__new__r   Nc                 C   s   || _ || _t|| _|| _|| _| jdkrTt| _t| _	t
| _d| _t|t  | _nH| jrhJ 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origNextTableOffsetr0   r(   fontTools.ttLibr|   searchRangeentrySelector
rangeShiftrZ   directoryOffset
formatSizenextTableOffsetr   writer   r:   )r<   r$   r5   r   r&   r'   r|   r   r   r   r@      s<    



zSFNTWriter.__init__c                 C   s$   || j v 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 v 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sJ | || dS )zWrite raw table data to disk.r   rG   NrH   rI   rJ   Tr   rh   r~   )r:   r   r)   r7   r   r   rL   rM   	headTableuncompressedsaveDatar$   r&   r   
origOffset
origLengthlengthr   rZ   r   )r<   r7   r>   r?   r   r   r   __setitem__  s$    
"

zSFNTWriter.__setitem__c                 C   s
   | j | S rA   rB   rC   r   r   r   rQ   .  s    zSFNTWriter.__getitem__c           
      C   s  t | j }t|| jkr2td| jt|f | jdkrd| _d| _d| _	|  j	dt| 7  _	|D ] \}}|  j	|j
d d@ 7  _	qj| jr| jnt }|jd	ur|jd	ur|j| _|j| _n6t| d
rt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J 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}   rh   r   Nr   z>HHr
   rH   ro   r~   rz   rG   r   )'r8   r:   r9   r.   r5   r   r&   r   reservedZtotalSfntSizer   r'   r;   majorVersionminorVersionhasattrstructr/   r   metaDatametaOrigLengthr$   r   rZ   
metaOffsetrr   
metaLengthr   privData
privOffset
privLengthr   r   packr   r   r   toStringwriteMasterChecksum)
r<   r:   r7   r?   r>   ZcompressedMetaDataoffZ	paddedOff	directoryZseenHeadr   r   r   rS   1  sl    






zSFNTWriter.closec                 C   s  t | j }g }tt|D ]}|| j||  j q| jtkrddl	m
} || jd\| _| _| _tt| }t| j }|D ]:\}}t }	|j|	_|j|	_|j|	_|j|	_||	  }qtt| jt  }
|
t|ksJ |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   rL   sum)r<   r   tagsZ	checksumsr    r|   r:   r7   r?   Z	sfntEntryZdirectory_endrP   checksumadjustmentr   r   r   _calcMasterChecksumx  s0    
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)rc   rd   re   r   r@   r   r   rQ   rS   r   r   r   r   r   r   r   rx      s      
1G!rx   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__rc   r7   idrF   r   r   r   __repr__  s    
zDirectoryEntry.__repr__c                 C   sD   | | j || j}t|| jks*J t| jdr@| |}|S )N
decodeData)r   r   r   r   r.   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)rc   rd   re   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)rc   rd   re   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*J ||}t|| jksFJ |S Nr   )ru   r   r   
decompressr.   )r<   r   ru   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   rr   r   r   )r<   r>   ZcompressedDatar   r   r   r   r   .  s    


zWOFFDirectoryEntry.encodeData)rc   rd   re   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`J | 
|}t	||jks|J || _|jr|j|j |j|j}t	||jksJ || _d S rA   )r   r   r   r   r   r$   r   r   r   r.   _decompressr   r   r   )r<   readerr   r>   r   r   r   r@   ?  s&    
zWOFFFlavorData.__init__c                 C   s   dd l }||S r   )ru   r   )r<   r   ru   r   r   r   r   T  s    zWOFFFlavorData._decompress)N)rc   rd   re   ZFlavorr@   r   r   r   r   r   r;   <  s   
r;   c                 C   s   t | d }|r | dd|  7 } d}d}|d dks8J 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.   r4   r   r/   r   )r>   	remaindervalueZ	blockSizer    blockZlongsr   r   r   rL   Z  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spJ 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Versionr   r+   r,   )r$   r>   r<   r   r   r   r*   r  s     



r*   c                 C   sf   t  }d|_d|_||_| d | tt| | 	 }| t
jd|j gdg|j R   |S )Nr   r   r   r   )r   r   r   r+   r   r   r   r   r   rZ   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	getLoggerrc   rN   r   r	   r   rt   rv   rr   rx   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^   
  `
	


	
)(
