)Ej]\ dZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZmZdd lZdd lmZdd lZejeZGd d eZd ZdZdddddddddd ZefdZGddeZdZe jeZ dZ!e je!Z"dZ#e je#Z$dZ%e je%Z&d Z'e je'Z(Gd!d"eZ)Gd#d$e)Z*Gd%d&e)Z+Gd'd(Z,d)Z-d*Z.d+Z/ed,kr,dd l0Z0dd l1Z1e0j2e1j3j4d Sd S)-attLib/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. ) annotations)KeysView)BytesIO)SimpleNamespace)Tag)sstruct) TTLibErrorTTLibFileIsCollectionErrorN) OrderedDictcTeZdZdZddZdd ZeZdd Zdd ZddZ ddZ dZ dZ dS) SFNTReaderc@|r|turz|d}|dt|d}|d|dkr ddlm}t |St |S)zmReturn an instance of the SFNTReader sub-class which is compatible with the input file type. rwOF2) WOFF2Reader)r seekrreadfontTools.ttLib.woff2robject__new__)clsargskwargsinfile sfntVersionrs FC:\PYTHON\MyICR_Suite\python\Lib\site-packages\fontTools/ttLib/sfnt.pyrzSFNTReader.__new__!s  3C:%%!WF KKNNNfkk!nn--K KKNNNf$$======~~k222~~c"""rc>||_||_d|_d|_t|_|jd|jd|_|jd|jdkrt|j}|j }d|cxkr|ksntd|dz z||_ |j|j ||jt}t|tkrtdt!jt$||n|jdkrud|_t&|_|jt(}t|t(krtd t!jt*||na|jt}t|tkrtd t!jt$||t-|j|_|jd vrtd i}t/|jD]I}|} | |jt-| j} | || <Jt7t9|d |_|jdkrt?||_dSdS)Nrrsttcfz2specify a font number between 0 and %d (inclusive)'Not a Font Collection (not enough data)wOFFwoffz!Not a WOFF font (not enough data)z1Not a TrueType or OpenType font (not enough data))OTTOtruez1Not a TrueType or OpenType font (bad sfntVersion)c|djS)Nr )offset)is rz%SFNTReader.__init__..`s qt{r)key) filecheckChecksumsflavor flavorDataSFNTDirectoryEntryDirectoryEntryrrr readTTCHeadernumFontsr offsetTablesfntDirectorySizelenr runpacksfntDirectoryFormatWOFFDirectoryEntrywoffDirectorySizewoffDirectoryFormatrrange numTablesfromFiletagr sorteditemstablesWOFFFlavorData) selfr,r- fontNumberheaderr3datarBr)entryr?s r__init__zSFNTReader.__init__2s , 0 q9>>!,, q  w & &"49--FH ----X----0H!|%%DM INN6-j9 : : :9>>"344D4yy--- !JKKK N.d ; ; ; ;   ( ( DK"4D 9>>"344D4yy--- !DEEE N.d ; ; ; ;9>>"344D4yy--- !TUUU N.d ; ; ;t/00  #G G GPQQ Q,.t~&&  A''))E NN49 % % %ei..CF3KK!&=R=R"S"S"STT  ;& ,T22DOOO ! rr? str | bytesreturnboolc||jvSNrBrDr?s rhas_keyzSFNTReader.has_keyfsdk!!r KeysView[Tag]c4|jSrN)rBkeysrDs rrTzSFNTReader.keysks{!!!rbytesc|jt|}||j}|jr|dkr&t |dddz|ddz}nt |}|jdkr||jks Jd|zn&||jkrtd||S)zFetch the raw table data.headN r zbad checksum for '%s' table) rBrloadDatar,r- calcChecksumcheckSumlogwarning)rDr?rHrGchecksums r __getitem__zSFNTReader.__getitem__ns CHH%~~di((   @f}}'RaR;(>bcc(JKK'--"Q&&5>1113PSV3V1111U^++ 93??? rNonec0|jt|=dSrN)rBrrPs r __delitem__zSFNTReader.__delitem__s KC ! ! !rc8|jdSrN)r,closerUs rrgzSFNTReader.closes rct|jtr|jS|j}|d=|jj|d<|j|d<|S)Nr, _filename_filepos) isinstancer,r__dict__copynametellrDstates r __getstate__zSFNTReader.__getstate__sc di ) ) !=  ""$$ &M!Y^k INN,,j rcd|vrUt|dd|_|j|d|j|dS)Nr,rirbrj)openpopr,rrlupdaterps r __setstate__zSFNTReader.__setstate__sf   UYY{33T::DI INN599Z00 1 1 1 U#####rN)rr)r?rJrKrL)rKrR)r?rJrKrV)r?rJrKrc)rKrc) __name__ __module__ __qualname__rrIrQ __contains__rTrbrergrrrxrrr r s###"23232323h""""L""""$""""   $$$$$rr Fr rY 2d) r rrrr~rY cd|cxkrdksntd|ztr|dkrddlm}|||Sddlm}||t |S)aECompress '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). rrzBad compression level: %s)compress) numiterations) ValueError USE_ZOPFLIzlibr zopfli.zlib ZOPFLI_LEVELS)rGlevelrs rrrs OOOO!OOOO4u<=== B!!!!!!!xe$$$((((((xM%,@AAAArcLeZdZdZ d dZdZdZdZdZd Z d Z d Z dS) SFNTWritercd}|r d|vr |d}n|rt|dkr|d}|tur&|dkr ddlm}t|St|S)zpReturn an instance of the SFNTWriter sub-class which is compatible with the specified 'flavor'. Nr.rwoff2r) WOFF2Writer)r6rrrrr)rrrr.rs rrzSFNTWriter.__new__s  h&((H%FF  c$ii!mm!WF *    ======~~k222~~c"""rr$Nc&||_||_t||_||_||_|jdkrCt |_t|_ t|_ d|_ t|tzz|_nb|jrJd|jzt |_t|_ t"|_ ddlm}||d\|_|_|_|j|_|j|j z||j jzz|_|j|j|jd|j|jz zt;|_dS)Nr#wOFFUnknown flavor '%s'rgetSearchRange)r,r=rrr.r/r;directoryFormatr: directorySizer9r1 signaturer5sfntDirectoryEntrySizeorigNextTableOffsetr8r0fontTools.ttLibr searchRange entrySelector rangeShiftrodirectoryOffset formatSizenextTableOffsetrwriter rB)rDr,r=rr.r/rs rrIzSFNTWriter.__init__s~ "{++ $ ;& #6D !2D "4D #DN"I0F$FF  $ ${ G G$9DK$G G G?#6D !2D "4D  6 6 6 6 6 6DRN2EE AD d0$/ $y~~//    !$-88 9  t+,,, !5 8H8H!HIJJJ!mm rcP||jvrtd|z||j|<dS)Ncannot rewrite '%s' table)rBr )rDr?rHs rsetEntryzSFNTWriter.setEntry s5 $+  83>?? ?  Crc||jvrtd|z|}||_|j|_|dkr9t |dddz|ddz|_||_d|_ nt ||_| |j ||j dkr'|j |_|xj |jd zd zz c_ |j|jd zd zz|_|j d |j|j z z|j|j ksJ|||dS) zWrite raw table data to disk.rrXNrYrZr[Tr#rr)rBr r1r?rr(r]r^ headTable uncompressedsaveDatar,r.r origOffset origLengthlengthrror)rDr?rGrHs r __setitem__zSFNTWriter.__setitem__sl $+  83>?? ?##%% + &==)$rr([*@49*LMMEN!DN!%E  )$//EN ty$''' ;& #7E   $ $)9A)=(C C $ $#3 q8HB7NO !5 8H8H!HIJJJ#ty~~'7'77777 c5!!!!!rc|j|SrNrOrPs rrbzSFNTWriter.__getitem__1s{3rct|j}t||jkr&t d|jt|fz|jdkrd|_d|_d|_ |xj dt|zz c_ |D] \}}|xj |j dzdzz c_ !|j r|j n t}|j |j|j |_ |j|_nNt|d r0t!jd |jd d \|_ |_ndx|_ |_|jrt|j|_|jdd|j|_t3|j}t||_|j|ndx|_x|_|_|jr|jdd|j}|dzdz}|jd||z z|j|_t|j|_|j|jndx|_|_|jdd|j|_n|jrJd|jz tAj!|j"|}|j|j#|j$zd} |D]$\}}|dkrd} ||%z}%| r|&||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"rr[rrrNrz>HHrrYrrrrXr )'r@rBrAr6r=r r.rreserved totalSfntSizerr/rC majorVersion minorVersionhasattrstructr7rmetaDatametaOrigLengthr,rro metaOffsetr metaLengthrprivData privOffset privLengthrrpackrrrtoStringwriteMasterChecksum) rDrBr?rHrGcompressedMetaDataoff paddedOff directoryseenHeads rrgzSFNTWriter.close4s ))++,, v;;$. ( (?>3v;;/0  ;& $DNDM!#D    "s6{{"2 2  $ B B U""u'7!';r&AA"""&*oK4??>;K;KD ,1B1N$($5!$($5!!4-->;A=t~ac2<<8D%t'8'8=>=D%(9} L&)$-&8&8# q!$$$"&).."2"2%-dm%<%<""%&8"9"9  23333JKKK$/D4G} 6 q!$$$inn&& 1WN  S 9:::"&).."2"2"%dm"4"4  ....455$/ INN1a )..**DKK{ G G$9DK$G G G? L!5t<<  t+d.@@AAA  5 5JCf}}!ENN$4$44II  0  $ $Y / / / t+,,,  """""rc$g}|jD]'}||j|j(|jt krddlm}||jd\|_ |_ |_ tj t|}t|j}|D]Z\}}t }|j|_|j|_|j|_|j|_||z}[t.t1|jt2zz}|t1|ksJ|t5|t7|dz} d| z dz} | S)Nrrrl/ac)rBrTappendr^r1r0rrr=rrrrrr8r@rAr?rr(rrrr5r6rr]sum) rDr checksumsr?rrBrH sfntEntry directory_endrachecksumadjustments r_calcMasterChecksumzSFNTWriter._calcMasterChecksum{s ;##%% 8 8C   T[-6 7 7 7 7  "4 4 4 6 6 6 6 6 6DRNEE AD d0$/ %8$??IDK--//00F$ = = U.00 % %*^ "#(#3  #(#3  % (:(:(<(<< )C ,<,>J.(83zA!!rc||}|j|jdjdz|jt jd|dS)NrXrYz>L)rr,rrBr(rrr)rDrrs rrzSFNTWriter.writeMasterChecksums`!55i@@ t{6*1A5666  D*<==>>>>>rcdSNFr}rUs rreordersTableszSFNTWriter.reordersTablessur)r$NN) ryrzr{rrIrrrbrgrrrr}rrrrs###,' /$/$/$/$b!!! """<   E#E#E#N"""@??? rra > # 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 cDeZdZdZdZdZdZdZdZdZ dZ d Z d S) r1cd|_dSr)rrUs rrIzDirectoryEntry.__init__s!rcltj|j||j|dSrN)rr7formatrr)rDr,s rr>zDirectoryEntry.fromFiles,t{DIIdo$>$>EEEEErc<tj|j||dSrN)rr7r)rDstrs r fromStringzDirectoryEntry.fromStringst{C.....rc6tj|j|SrN)rrrrUs rrzDirectoryEntry.toStrings|DK...rct|dr$d|jj|jt |fzSd|jjt |fzS)Nr?z<%s '%s' at %x>z <%s at %x>)r __class__ryr?idrUs r__repr__zDirectoryEntry.__repr__sO 4   F$(?2d88'TT T4>#:BtHH"EE Erc||j||j}t ||jksJt |jdr||}|S)N decodeData)rr(rrr6rrrrDr,rGs rr\zDirectoryEntry.loadDatasl $+yy%%4yyDK'''' 4>< 0 0 )??4((D rct|jdr||}t||_||j||dS)N encodeData)rrrr6rrr(rrs rrzDirectoryEntry.saveDatas` 4>< 0 0 )??4((D$ii  $+ 4rc|SrNr})rDrawDatas rrzDirectoryEntry.decodeData src|SrNr})rDrGs rrzDirectoryEntry.encodeData s rN) ryrzr{rIr>rrrr\rrrr}rrr1r1s"""FFF//////FFF rr1ceZdZeZeZdS)r0N)ryrzr{sfntDirectoryEntryFormatrrrr}rrr0r0s %F'JJJrr0c2eZdZeZeZfdZdZdZ xZ S)r9ctt|ttdst|_dSdS)NzlibCompressionLevel)superr9rIrZLIB_COMPRESSION_LEVELr)rDrs rrIzWOFFDirectoryEntry.__init__sN  $''00222)+ABB ?(>D % % % ? ?rcddl}|j|jkr|}nA|j|jksJ||}t ||jksJ|SNr)rrr decompressr6)rDrrrGs rrzWOFFDirectoryEntry.decodeData%se ;$/ ) )DD;0000??7++Dt99//// rct||_|jst||j}|jst||jkr|}|j|_n|}t||_|SrN)r6rrrrr)rDrGcompressedDatars rrzWOFFDirectoryEntry.encodeData0ssd))  G%dD,EFFN   'N 3 3t F FG/DKK$Gg,,DKr) ryrzr{woffDirectoryEntryFormatrwoffDirectoryEntrySizerrIrr __classcell__)rs@rr9r9s` %F'J ? ? ? ? ?          rr9c eZdZdZddZdZdS)rCr#Ncrd|_d|_d|_d|_|r|j|_|j|_|jr|j|j|j|j}t||jksJ| |}t||j ksJ||_|j rc|j|j |j|j }t||j ksJ||_dSdSdSrN)rrrrrr,rrrr6 _decompressrrr)rDreaderrrGs rrIzWOFFFlavorData.__init__As=     % & 3D  & 3D   %   !2333 +**6+<==7||v'88888''004yyF$99999 $   %   !2333{''(9::4yyF$55555 $  % % % %rc4ddl}||Sr)rr)rDrrs rrzWOFFFlavorData._decompressVs w'''rrN)ryrzr{FlavorrIrr}rrrCrC>s< F%%%%*(((((rrCc8t|dz}|r |dd|z zz }d}d}|dzdksJtdt||D]L}||||z}tjdt|dzz|}|t |zdz}M|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 rrri>%dLr)r6r<rr7r)rG remaindervalue blockSizer)blocklongss rr]r]\sD A I( Y'' EI q=A     1c$ii + +22QY&' fE a8%@@U#z1 Lrc|d|t}t|tkrt dt }t jt|||j dkrt d|j dks|j dksJd|j ztjd|j z||j d z|_ |j dkr |S) Nrr!ttcfzNot a Font Collectionizunrecognized TTC version 0x%08xrr)rr ttcHeaderSizer6r rrr7ttcHeaderFormatTTCTagVersionrr3r4)r,rGrDs rr2r2tsIIaLLL 99] # #D 4yyM!!BCCC   D N?D$/// {f0111 <: % %)C)C)C)DL8*D)C C} $-!*; < <D |z!! Krcdt}d|_d|_||_|d|t jt|| }|tjd|jzgdg|jzR|S)Nr r rr) rrrr3rrrrrror)r,r3rDr(s rwriteTTCHeaderrs   DDKDLDMIIaLLLJJw|OT22333 YY[[FJJv{6DM1JaS4=5HJJJKKK Mr__main__)5__doc__ __future__rcollections.abcriortypesrfontTools.misc.textToolsrfontTools.miscrrr r r collectionsr logging getLoggerryr_rr rrrrrrcalcsizerr8r5rrr;r:rrr1r0r9rCr]r2rsysdoctestexittestmodfailedr}rrr%s<  #"""""$$$$$$!!!!!!((((((""""""BBBBBBBB ######g!!|$|$|$|$|$|$|$|$@          0BBBB&YYYYYYYY| ! 11 %G$%899*)*BCC"%G$%899*)*BCC&&&&&V&&&R(((((((( %%%%%%%%P((((((((<0(    zJJJNNN CH_W_   %&&&&& r