)EjhddlmZddlZddlZddlZddlmZddlmZddl m Z ddl m Z m Z mZmZmZddlmZmZmZmZmZddlmZmZmZmZmZmZmZmZm Z dd l!m"Z"m#Z#ddl$Z$e$j%d Z&d Z' ddl(Z)n#e*$rddl)Z)YnwxYwd Z'n #e*$rYnwxYwGd deZ+GddeZ,dZ-ej.e-Z/dZ0dZ1ej.e1Z2dZ3ej.e3Z4dZ5dZ6e2e4zde6zzZ7dZ8dZ9ej.e9Z:dZ;dZGdd ed!Z?Gd"d#ed$Z@Gd%d&ed'ZAGd(d)eZBd*ZCd+ZDd,ZEd-ZFd.ZGd3d/ZHd0ZId3d1ZJeKd2krejLeJdSdS)4)BytesION) OrderedDict)sstruct) calcIntBounds)Tagbytechrbyteord bytesjoinpad)TTFont TTLibErrorgetTableModule getTableClassgetSearchRange) SFNTReader SFNTWriterDirectoryEntryWOFFFlavorDatasfntDirectoryFormatsfntDirectorySizeSFNTDirectoryEntrysfntDirectoryEntrySize calcChecksum) ttProgram_g_l_y_fzfontTools.ttLib.woff2FTc@eZdZdZd dZdZdZd dZd Zd Z d Z dS) WOFF2Readerwoff2rcts)tdtd||_t |jd}|dkrtd|jdt|_ |jt}t|tkrtdtjt||t!|_d}t%|jD]_}| }||jt |j} ||j| <||_||jz }`|} |j|j} t3j| } t| | kr!td| t| fzt7| |_|jdd |j|jkrtd t=||_tAd d |_!dS) NzfThe WOFF2 decoder requires the Brotli Python extension, available at: https://github.com/google/brotliNo module named brotliswOF2z Not a WOFF2 font (bad signature)rz"Not a WOFF2 font (not enough data)zAunexpected size for decompressed font data: expected %d, found %dz4reported 'length' doesn't match the actual file sizeF recalcBBoxesrecalcTimestamp)" haveBrotlilogerror ImportErrorfilerreadr seekWOFF2DirectoryEntryrwoff2DirectorySizelenrunpackwoff2DirectoryFormatrtablesrange numTablesfromFiletagoffsetlengthtotalCompressedSizebrotli decompressrtransformBuffertellWOFF2FlavorData flavorDatar ttFont) selfr+checkChecksums fontNumber signaturedatar8ientryr7totalUncompressedSizecompressedDatadecompressedDatas GC:\PYTHON\MyICR_Suite\python\Lib\site-packages\fontTools/ttLib/woff2.py__init__zWOFF2Reader.__init__/s< 8 II3   677 7  q))**   ?@@ @ q1y~~011 t99* * *ABB B+T4888!mm t~&& # #A''))E NN49 % % %ei..C$DK !EL el "FF &(@AA!,^<<  $9 9 9S(#.>*?*?@A  ''788 q! ;$)..** * *STT T)$//%GGG c|jt|}t|dsA|jr|||_n||j|_|jS)z9Fetch the raw table data. Reconstruct transformed tables.rF)r3rhasattr transformedreconstructTablerFloadDatar=)rBr7rHs rL __getitem__zWOFF2Reader.__getitem__ash CHH%uf%% B  B!22377 "^^D,@AA zrNcl|jt|}||j}|dkr0t |dr|jnd}|||}nI|dkr|}n.|dkr||}ntd|z|S)z4Reconstruct table named 'tag' from transformed data.glyfpaddingNlocahmtxz#transform for table '%s' is unknown) r3rrSr=rPrW_reconstructGlyf_reconstructLoca_reconstructHmtxr )rBr7rHrawDatarWrFs rLrRzWOFF2Reader.reconstructTableks CHH%..!566 &==&-dI&>&>HdllDG(('::DD F]]((**DD F]]((11DDBSHII I rNNct|jd<tx}|jd<|||j|r||_||j}|S)zReturn recostructed glyf table data, and set the corresponding loca's locations. Optionally pad glyph offsets to the specified number of bytes. rXrV)WOFF2LocaTablerAWOFF2GlyfTable reconstructrWcompile)rBrFrW glyfTables rLrZzWOFF2Reader._reconstructGlyf{so-.. F*8*:*:: DK'dDK000  ( 'I   -- rNcXd|jvr%|d|jd_|jd}||j}t ||jdjkr1td|jdjt |fz|S)z%Return reconstructed loca table data.rXrVzMreconstructed 'loca' table doesn't match original size: expected %d, found %d)rArRr3rFrbr0 origLengthr )rB locaTablerFs rLr[zWOFF2Reader._reconstructLocas  $ $'+'<'+I3t99*UV  rNcd|jjvrd}nd}|D]}||tx}|jd<|||j||j}|S)z%Return reconstructed hmtx table data.rV)maxphhearV)rhheadrirXrVrY)r@transformedTables_decompileTableWOFF2HmtxTablerArarb)rBrFtableDependenciesr7 hmtxTables rLr\zWOFF2Reader._reconstructHmtxs T_6 6 6 8  !I $ & &C   % % % %*8*:*:: DK'dDK000  -- rNc||}|j|r |j|St|}||}||jj|<|||jdS)z5Decompile table data and store it inside self.ttFont.N)rAisLoadedrr3 decompilerBr7rF tableClasstables rLrlzWOFF2Reader._decompileTablesuCy ;   $ $ $;s# #"3''  3"' 3 dk*****rN)rrN) __name__ __module__ __qualname__flavorrMrTrRrZr[r\rlrNrLrr,s F0H0H0H0Hd       $+++++rNrceZdZdZ ddZdZdZddZd Zd Z d Z d Z d Z dZ dZdZdZdZdZdZdZdZdS) WOFF2WriterrNcts)tdtd||_||_t ||_t||_ t|_ t|_ t|_t d|_d|_t%|_t)|_t-dd|_dS)NzfThe WOFF2 encoder requires the Brotli Python extension, available at: https://github.com/google/brotlir!)rFwOF2rFr$)r'r(r)r*r+r5r sfntVersionr?r@r2directoryFormatr/ directorySizer.rrEnextTableOffsetrr=rr3r rA)rBr+r5rrzr@s rLrMzWOFF2Writer.__init__s 8 II3   677 7 "{++)z:::3/1V &yy!mm %GGG rNc||jvrtd|z|dkr|xjdzc_dS|}t ||_t |j|_||_||j|<dS)z4Associate new entry named 'tag' with raw table data.zcannot rewrite '%s' tableDSIGN) r3r r5rrr7getKnownTagIndexflagsrF)rBr7rFrHs rL __setitem__zWOFF2Writer.__setitem__s $+  83>?? ? &== NNa NN F##%%HH &uy11    CrNct|j|jkr+td|jt|jfz|jdvrd}n|jdkrd}ntd|r-d|jjvrd|jvr|d |tt|j |_| |_ |}tj|tj }t||_||_|\|_|_d |_|}|jd |jt;||zd |d S)zJAll tags must have been specified. Now write the table data and directory.z-wrong number of tables; expected %d, found %d)r~trueTOTTOFz1Not a TrueType or OpenType font (bad sfntVersion)rVr")rWmodersizeN)r0r3r5r rr@rk_normaliseGlyfAndLoca_setHeadTransformFlagrsorteditems#_calcSFNTChecksumsLengthsAndOffsets totalSfntSize_transformTablesr;compress MODE_FONTr:_calcTotalSizer9 _getVersion majorVersion minorVersionreserved_packTableDirectoryr+r-writer _writeFlavorData)rB isTrueTypefontDatacompressedFont directorys rLclosezWOFF2Writer.closes t{  t~ - -?>3t{#3#345   ; ; ;JJ   ' 'JJPQQ Q  2$/;;;$+%%  & &q & 1 1 1 ""$$$"&):):)<)<"="=>> !EEGG((**8HIII#&~#6#6 ))++ /3/?/?/A/A,4, ,,..  q I6Q???@@@ rNr"c|jdkrdSdD] }||jvr||!||jd_dD]}||dS)zRecompile glyf and loca tables, aligning glyph offsets to multiples of 'padding' size. Update the head table's 'indexToLocFormat' accordingly while compiling loca. rN)rhrjrXrVfvarrVrVrX)rr3rlrArW _compileTable)rBrWr7s rLrz!WOFF2Writer._normaliseGlyfAndLocas  v % % F; * *Cdk!!$$S)))&- F## $ $C   s # # # # $ $rNc|d|jdxjdzc_|ddS)zSet bit 11 of 'head' table flags to indicate that the font has undergone a lossless modifying transform. Re-compile head table data.rjiN)rlrArrrBs rLrz!WOFF2Writer._setHeadTransformFlag.sM V$$$ F!!W,!! 6"""""rNct|}||jvrtd|z|j|rdS|j|j}|dkrt }n+|dkrt}n|dkrt}nt|}||}||jj|<| ||jdS)z@Fetch table data, decompile it, and store it inside self.ttFont.zmissing required table: %sNrXrVrY) rr3r rArqrFr_r`rmrrrrss rLrlzWOFF2Writer._decompileTable5s#hh dk ! !9C?@@ @ ;   $ $  F{3$ &=='JJ F]]'JJ F]]'JJ&s++J 3"' 3 dk*****rNcp|j||j|j|_dS)z3Compile table and store it in its 'data' attribute.N)rArbr3rFrBr7s rLrzWOFF2Writer._compileTableIs. $ C 0 8 8 E E CrNczttt|jzz}|jD]|\}}|j}||_t||_|dkr+t|dddz|ddz|_ nt||_ ||jdzdzz }}|S)zCompute the 'original' SFNT checksums, lengths and offsets for checksum adjustment calculation. Return the total size of the uncompressed font. rjNs ) rrr0r3rrF origOffsetrercheckSum)rBr8r7rHrFs rLrz/WOFF2Writer._calcSFNTChecksumsLengthsAndOffsetsMs#%;c$+>N>N%NN+++-- 2 2JC:D%E "4yyE f}}!-d2A2h.DtBCCy.P!Q!Q!-d!3!3 u'!+r1 1FF rNc|jj}|jD]\}}d}||vr||}|d|_|)|dkr|d|j}d|_|j|_ | |j ||xj|j z c_| |j }|S)zReturn transformed font data.NTrVrXF)r@rkr3rtransformTablerQdiscardrFrr8saveDatar=r9writeMasterChecksumgetvalue)rBrkr7rHrFrs rLrzWOFF2Writer._transformTables]s O=+++-- 1 1JCD'''**3//#(,E%|&==&--f555z$)!/EL NN4/ 6 6 6  EL 0    """'0022rNcr|dkrd}n|dkrBdD]}|||jd}||j}ne|dkrMd|jvrdSdD]}|||jd}||j}nt d|z|S) zReturn transformed table data, or None if some pre-conditions aren't met -- in which case, the non-transformed table data will be used. rXrNrV)rhrjrXrVrYN)rhrjrirXrVrYz#Transform for table '%s' is unknown)rlrA transformr3r )rBr7rFrcros rLrzWOFF2Writer.transformTableus &==DD F]]7 * *$$S)))) F+I&&t{33DD F]]T[((G * *$$S)))) F+I&&t{33DDBSHII I rNcg}|jD]'}||j|j(t |jd\|_|_|_tj t|}t|j }|D]Z\}}t}|j|_|j|_|j|_|j|_||z}[t*t-|jt.zz}|t-|ksJ|t1|t3|dz}d|z dz} | S)zCalculate checkSumAdjustment.ll/ac)r3keysappendrrr5 searchRange entrySelector rangeShiftrpackrrrrr7rr8rer9toStringrr0rrsum) rB checksumsr7rr3rH sfntEntry directory_endchecksumchecksumadjustments rL_calcMasterChecksumzWOFF2Writer._calcMasterChecksumsq ;##%% 8 8C   T[-6 7 7 7 7AO NBA A =$,doL!4d;;  ))++,,  9 9JC*,,I!IIM!&I $/I $/I !I$6$6$8$88II)C ,<,>J.(83zA!!rNc|}|j|jdjdz|jt jd|dS)z0Write checkSumAdjustment to the transformBuffer.rjrz>LN)rr=r-r3r8rstructr)rBrs rLrzWOFF2Writer.writeMasterChecksumsd!5577 !!$+f"5"HHr"r)rr)r@rrr3rr1rFrBrFs rLrzWOFF2Writer._getVersionsd   (T->-J$d&77 7$$}UDK,?,DQqS,IJJJtrNctj|j|}|jD]}||z}|S)z"Return WOFF2 table directory data.)rrrr3rr)rBrrHs rLrzWOFF2Writer._packTableDirectorysOL!5t<< ['')) 5 5E!ENN$4$44IIrNc|j}|jj}|r|rt|d}|r]|j|j|j|jksJ|j||r_|j|j |j|j ksJ|j|dSdS)zrr)rBrrs rLrzWOFF2Writer._writeFlavorDatas!4?+  A( A!$%7a!@!@!@   0 INN4? + + +9>>##t6666 IOO. / / /  & INN4? + + +9>>##t6666 IOOH % % % % % & &rNcdS)NTr{rs rLreordersTableszWOFF2Writer.reordersTablesstrN)r~NN)r")rwrxryrzrMrrrrrlrrrrrrrrrrrrr{rNrLr}r}sH F ' H H H HD!!!$4 4 4 l $ $ $ $###+++(FFF 0,""":JJJ 2    & & &rNr}a > # big endian signature: 4s # "wOF2" sfntVersion: 4s length: L # total woff2 file size numTables: H # number of tables reserved: H # set to 0 totalSfntSize: L # uncompressed size totalCompressedSize: L # compressed 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 )?cmaprjrirYrhnamezOS/2postzcvt fpgmrVrXprepzCFF VORGEBDTEBLCgasphdmxkernLTSHPCLTVDMXvheavmtxBASEGDEFGPOSGSUBEBSCJSTFMATHCBDTCBLCCOLRCPALzSVG sbixacntavarbdatblocbslncvarfdscfeatfmtxrgvarhstyjustlcarmortmorxopbdproptrakZapfSilfGlatGlocFeatSillz5 > # big endian flags: B # table type and flags z5 > # big endian tag: 4s # 4-byte tag (optional) ?r#ra > # big endian version: H # = 0x0000 optionFlags: H # Bit 0: we have overlapSimpleBitmap[], Bits 1-15: reserved numGlyphs: H # Number of glyphs indexFormat: H # Offset format for loca table nContourStreamSize: L # Size of nContour stream nPointsStreamSize: L # Size of nPoints stream flagStreamSize: L # Size of flag stream glyphStreamSize: L # Size of glyph stream compositeStreamSize: L # Size of composite stream bboxStreamSize: L # Comnined size of bboxBitmap and bboxStream instructionStreamSize: L # Size of instruction stream zF > # big endian xMin: h yMin: h xMax: h yMax: h rcf t|S#t$r tcYSwxYw)zEReturn index of 'tag' in woff2KnownTags list. Return 63 if not found.)woff2KnownTagsindex ValueErrorwoff2UnknownTagIndex)r7s rLrrsB$##C((( $$$####$s 00ceZdZdZdZdZedZejdZedZ e jdZ dS) r.c|}|t}||}t |t |z }|||zdSrv)r>r,woff2DirectoryEntryMaxSize fromStringr0r-)rBr+posrFleftconsumeds rLr6zWOFF2DirectoryEntry.fromFilesdiikkyy344t$$t99s4yy( #.!!!!!rNc`t|dkrtdtjt||\}}|jdzdkrFt|t krtdtjt||\}}nt|jdz|_ t|j |_ t|\|_ }|j |_ |jr4s) rrrrr7tobytes packBase128rerQr9rs rLrzWOFF2DirectoryEntry.toStringstz"" J $ & & FKtx'7'7'9'9:: :D DO,,,   - K ,, ,D rNc|jdz S)zReturn bits 6-7 of table entry's flags, which indicate the preprocessing transformation version number (between 0 and 3). rrs rLtransformVersionz$WOFF2DirectoryEntry.transformVersions zQrNcNd|cxkrdksnJ|xj|dzzc_dS)Nrrr3r4)rBvalues rLr5z$WOFF2DirectoryEntry.transformVersions5EQ eqj rNc@|jdvr |jdkS|jdkS)zCReturn True if the table has any transformation, else return False.>rVrXrr)r7r5rs rLrQzWOFF2DirectoryEntry.transformeds. 8' ' '(A- -(A- -rNcZ|jdvr |sdnd|_dSt||_dS)N>rVrXrr)r7r5int)rB booleanValues rLrQzWOFF2DirectoryEntry.transformeds? 8' ' '-9$@AAqD ! ! !$' $5$5D ! ! !rNN) rwrxryr6r$rpropertyr5setterrQr{rNrLr.r.s""",X !!! . .X .66666rNr.c*eZdZdZddZfdZxZS)r_zSame as parent class. The only difference is that it attempts to preserve the 'indexFormat' as encoded in the WOFF2 glyf table. Nc2t|pd|_dS)NrXrtableTagrs rLrMzWOFF2LocaTable.__init__CM6** rNc t|j}n'#t$r|gd}YnwxYwd|vrt |ddr|dj}|dkry|dkrt dtd|jDst dtjd}|jD]}| |d zntjd |j}tj d kr| | }n(tt||}|S) NrrV indexFormatiz,indexFormat is 0 but local offsets > 0x20000c3(K|] }|dzdkVdS)r#rNr{).0ls rL z)WOFF2LocaTable.compile..s*>>!1q5A:>>>>>>rNz5indexFormat is 0 but local offsets not multiples of 2Hr#Ibig)max locationsAttributeErrorsetrPrDr allarrayrsys byteorderbyteswapr0superr_rb)rBrA max_locationrDrMlocationrF __class__s rLrbzWOFF2LocaTable.compiles t~..LL    HHRLLLLLL  V  v F F  .4Ka7**$%STTT>>t~>>>>>$O"K,, $44H$$X]33334"KT^<< }%%""$$$$$&&DD..66v>>D s !<<rv)rwrxry__doc__rMrb __classcell__rXs@rLr_r_sV++++rNr_rXc~eZdZdZdZddZdZdZdZdZ d Z d Z d Z d Z d ZdZdZdZdZdZdZdZdS)r`z1Decoder/Encoder for WOFF2 'glyf' table transform.)nContourStream nPointsStream flagStream glyphStreamcompositeStream bboxStreaminstructionStreamNc2t|pd|_dS)NrVr@rs rLrMzWOFF2GlyfTable.__init__rBrNcvt|}|tkrtdtjt ||\}}t}|jD]=}t||dz}t|||d|||d}||z }>|j tz}d|_ |r4|j dzdz } tj d|d| |_ || z }||krtd||fz|j dzd z d z} |jd| } tj d| |_|j| d|_tj d |j|_t"jd kr|jt|j|j ksJd |vr|j|d _ ||_n#d|_YnxYw|j@dg|_|jdt3d|j DnHt|j|j kr+tdt|j|j fzix} |_t7|jD]\} }|| }|| |< dS)z"Decompile transformed 'glyf' data.znot enough 'glyf' dataSizeNrBzJincorrect size of transformed 'glyf' table: expected %d, received %d bytesrr#hrKrjz.notdefcg|]}d|zS)z glyph%.5dr{)rFrGs rL z.WOFF2GlyfTable.reconstruct..8s#V#V#VK!O#V#V#VrNrz2incorrect glyphOrder: expected %d glyphs, found %d)r0woff2GlyfTableFormatSizer rr)woff2GlyfTableFormat subStreamsgetattrsetattr optionFlagswoff2OverlapSimpleBitmapFlagoverlapSimpleBitmap numGlyphsrQrb bboxBitmapr]rRrSrTrDindexToLocFormat getGlyphOrder glyphOrderextendr4glyphs enumerate _decodeGlyph)rBrFrA inputDataSizer.r8streamrhasOverlapSimpleBitmapoverlapSimpleBitmapSizebboxBitmapSizervr{glyphID glyphNameglyphs rLrazWOFF2GlyfTable.reconstruct sD 3 3 3566 6o&:D$GG t)o  F4&11D D&$uu+ . . .;D dNFF!%!14P!P#' ! .'+~'9a&? #',{3=U>U=U8V'W'WD $ - -F ] " "\=)*   >B.14:__n_5 +c:66/.//:#k#t/BCC =E ! !   ( ( * * *4&''4>9999 V  .2.>F6N + #$2244DOO #"DOOO ? "(kDO O " "#V#VU1dn=U=U#V#V#V W W W W4?##t~55 H4?++T^<= "!"+DO"<"< & & GY%%g..E %F9   & &s G G*c tj_tjjksJd|vrj|d_|dj_jD]}t|djdzdz dz}tjddg|z_ tjddgjd zd z z_ tjD]*} |#t$rYd SwxYwtj }j jz_jD]1}t|d ztt#|2d_d_|rxjt(zc_t+jt.}|t1fd jDz }|r|j z }|S)zReturn transformed 'glyf' datarhrjrNrirr#rhrrgrNrfc0g|]}t|Sr{)rp)rFsrBs rLrlz,WOFF2GlyfTable.transform..bs#EEE74++EEErN)r0r{ruryrwrDrorqrQrvrtr4 _encodeGlyphNotImplementedErroranyr0rbrpversionrrrsrrrnr )rBrArrrrrFs` rLrzWOFF2GlyfTable.transformEs(T[))4?##t~5555 V  '+~F6N $!&>:o ' 'F D&# & & & &>B.14:+cA3+?@@#(;sQCDNQ!>/1133doEo G GF D&6/3wtV/D/D+E+E F F F F  ! =    < <  |0$77 EEEET_EEEFFF ! 7 D,4466 6D s+D DDc\td}|j||_|jdkr|S|r||n+|||||||||S)NrVr) rGlyphr]numberOfContours isComposite_decodeComponents_decodeCoordinates_decodeOverlapSimpleFlag _decodeBBox)rBrrs rLr}zWOFF2GlyfTable._decodeGlyphgsv&&,,..!%!4W!=  !Q & &L     :  " "5 ) ) ) )  # #E * * *  ) )% 9 9 9 %((( rNc&|j}g|_d}d}|r\td}|||\}}}||z}|j||\||_|r||dSdS)NrrrV)ra componentsrGlyphComponentrrr_decodeInstructions)rBrrFmorehaveInstructions component haveInstrs rLrz WOFF2GlyfTable._decodeComponentsts# /&v..==??I$-$7$7d$C$C !D)T/);    # #I . . .  / $  ,  $ $U + + + + + , ,rNc|j}g}d}t|jD].}t|\}}||z }||/||_||_||||dSNr)r^r4runpack255UShortrendPtsOfContours_decodeTripletsr)rBrrFrendPointrG ptsOfContours rLrz!WOFF2GlyfTable._decodeCoordinatess!u-.. . .A!0!6!6 L$  $H  # #H - - - -!1! U###   '''''rNc|j |jdkrdS|dz }|dz}|j|d|z zr!|jdxxtjzcc<dSdSNrrrg)rtrrrflagOverlapSimplerBrrbytebits rLrz'WOFF2GlyfTable._decodeOverlapSimpleFlagsq  # +u/E/J/J F!|k  #D )TS[ 9 9 KNNNh8 8NNNNN 9 9rNc|j}|j}t|\}}tj|_|j|d|||_||d|_dSrv)r`rcrrProgramprogram fromBytecode)rBrr`rcinstructionLengths rLrz"WOFF2GlyfTable._decodeInstructionss{&  2)8)E)E&;!)++  ""#45G6G5G#HIII&!23D3E3E!FrNc$t|j|dz d|dzz z}|r|std|z|r*t jt |j|\}|_dS||dS)Nrrrgz%no bbox values for composite glyph %d) boolrvrr rr) bboxFormatrb recalcBounds)rBrrhaveBBoxr.s rLrzWOFF2GlyfTable._decodeBBoxs1 5'A+9NOPP      Px PDwNOO O  %%,_ZRW%X%X "E4???   t $ $ $ $ $rNcJd}|jddz}|}|t|jkrtd|jd|}|j|d|_t jd|}t jd|j}t|}||ksJd} d} t dj||_ t jd|_ d} t|D] } || } t| dz  }| d z} | d krd}n| d krd }n | d krd}nd}| |z|ksJ| dkrd}|| | dzdz|| z}nY| dkr"|| | dz dzdz|| z}d}n1| d krD| dz }|| }|| d|dzz|dz z}|| dz d|dzd zz|dzz}n| d krK| d z }|| d|dzdzz|| z}|| dz d|dzd z dzz|| dzz}n| d krH|| dz}|| || dz|dz z}|| dz |dzdz|| d zz}nH|| || dz|| dzz}|| dz || d zdz|| dzz}| |z } | |z } | |z } | | f|j | <|j t| | }|j|d|_dS)NcBd|kr|dks Jd|dzr|n| S)Nrizinteger overflowrr{)flagbasevals rLwithSignz0WOFF2GlyfTable._decodeTriplets..withSigns4<)?29)MNNBYXdA"(q$9H\hr) getGlyphNamer]rrrr_encodeComponents_encodeCoordinates_encodeOverlapSimpleFlag _encodeBBox)rBrrrs rLrzWOFF2GlyfTable._encodeGlyphs%%g.. Y v{41GHHH  !Q & & F     :  " "5 ) ) ) )  # #E * * *  ) )% 9 9 9 %(((((rNct|jdz }d}d}t|jD]B\}}||krt|d}d}|xj||||z c_C|r||dSdS)Nrrr)r0rr|rPrarb_encodeInstructions)rBr lastcomponentrrrGrs rLrz WOFF2GlyfTable._encodeComponentssE,--1 %e&677 T TLAyM!!#*5)#<#<   I$5$5d>%%% 7< E:::rNc>t|jt|jksJ|j}|t jd}t jd}t |D]\}\}}|j|tjz}t|} t|} |rdnd} |dkrdnd} |dkrdnd} | d| zz}|dkr@| dkr:| | | dzdz z| z| | d z|dkrC| dkr=| | d z| dzdz z| z| | d z| d kr_| d krY| | d z| dz d zz| dz d zdz z|z| | dz dzdz| dz dzzW| dkrt| dkrn| | dzd| dz dzdz zz| dz dzdz z|z| | dz d z| | dz d z| dkrt| dkrn| | dz|z| | dz | | dzdz| dz z| | d zK| | dz|z| | dz | | d z| | dz | | d z|xj | z c_ |xj | z c_ dS)Nrhrrrr#iirgrArrrr"irrirr3irr)r0rrcopyabsoluteToRelativerQr|r flagOnCurveabsrr_r0r`)rBrrrrrGrrrabsXabsY onCurveBitxSignBitySignBit xySignBitss rLrzWOFF2GlyfTable._encodeTriplets0s 5$%%U[)9)99999',,.. &&((( C  ;s##";//, -, -IAv1k!nx';;Gq66Dq66D%.3JUUqqHUUqqH!AL0JAvv$++ ZD5LQ+>?(JKKKt ,,,,aD4KK Z"_!0CDxOPPPt ,,,,tbyy qD(*T)a/1! !4!8s"2q!8dQh#=M NOOOOs  dQh%/A567U*q02! !T 1222T 12222 Z#- :;;; ***$*!2tqy ABBBt ,,,, Z#- :;;; ***t ,,, ***t ,,,, 5==??* H,,...rNrv)rwrxryrYrorMrarr}rrrrrrrrrrrrrr{rNrLr`r`s.;;J++++9&9&9&v   D    , , , ( ( (999GGG%%%H<H<HBrrz#Bits 2-7 of '%s' flags are reservedr#z?either bits 0 or 1 (or both) must set in transformed '%s' flagsrVrirIrKrjrztoo much '%s' table datar)rr1r rAryr0minr:numberOfHMetricsrQrRrSrTr|rprmetricsr4)rBrFrAr hasLsbArrayhasLeftSideBearingArrayrc headerTableryruradvanceWidthArraylsbArrayrGrrrnumberOfSideBearingsleftSideBearingArray advanceWidthlsb lastAdvances rLrazWOFF2HmtxTable.reconstructms=tBQBx00ABBx :  " "BT]RSS Sai1n "'!)q.  2 Q-   6N Vn )  OO s;#?@@)LL4yyA 000000!KT2HA8H4H2H-IJJ =E ! !  & & ( ( (A((**+  &t99$4 44444{3-Cq3C/C-C(DEEH}%%!!###,,../DD{3''H )* 5 5 & & 9(((E!),ufa00%%%%(+;; " 2t99$8 88888#(;sD9S1?S;S9S4T#U#U }%%$--///00223DD$);s#3#3 )* 5 5 2 2 9'''!),ufa00$++D1111  I7$-GHH H '(( : :A"1 I 1! 4hqk#L'3S&9DL # #'+ +,, M MA"1'7#78I'24H4K&LDL # # M MrNc ||d}|d}|jd}tD]<}|}j|d}|t ||ddkrd}n=d}tt D]<}|}j|d}|t ||ddkrd}n=|r|rdSd} |s| dz} |s| dz} t jd | } tjd fd tD} tj d kr| | | z } |rjtjd fdtD} tj d kr| | | z } |rxtjd fdtt D} tj d kr| | | z } | S)NrVriFrrrTr#rrIcHg|]\}}|k j|dS)rrrFrGrrrBs rLrlz,WOFF2HmtxTable.transform..s?    Ay''' Y'*'''rNrKrjcHg|]\}}|k j|dSrrrs rLrlz,WOFF2HmtxTable.transform..s?$9+++L+A.+++rNcBg|]}j|dSrr)rFrGryrBs rLrlz,WOFF2HmtxTable.transform..s9LA/2rN)rxrr4rrpr0rrrQr|rRrSrTr0)rBrArVrirrGrr rrrFrr r ryrs` @@rLrzWOFF2HmtxTable.transforms))++ f~f~0 '((  A"1 I,y)!,Cgd9ovq9999" : #('Z99  A"1 I,y)!,Cgd9ovq9999*.':  2  F  VOE&  VOE{4''!K      $-j$9$9      =E ! !  & & ( ( ( !))+++  '{(1*(=(=H}%%!!### H$$&& &D " 3#(;"#3S__EE$$ }%%$--/// (0022 2D rNrv)rwrxryrMrarr{rNrLrmrmisR++++HMHMHMTLLLLLrNrmrYc*eZdZdZdfd ZdZxZS)r?rNc,tstd|"|td|td|d|vrd|vsd|vrd|vrtdt t |||r$d |jD}nK|rI|j |_ |j |_ |j |_ |j |_ |t|d r|j}|t}t!||_dS) a Data class that holds the WOFF2 header major/minor version, any metadata or private data (as bytes strings), and the set of table tags that have transformations applied (if reader is not None), or will have once the WOFF2 font is compiled. Args: reader: an SFNTReader (or subclass) object to read flavor data from. data: another WOFFFlavorData object to initialise data from. transformedTables: set of strings containing table tags to be transformed. Raises: ImportError if the brotli module is not installed. NOTE: The 'reader' argument, on the one hand, and the 'data' and 'transformedTables' arguments, on the other hand, are mutually exclusive. r!Nz4'reader' and 'data' arguments are mutually exclusivezA'reader' and 'transformedTables' arguments are mutually exclusiverVrXz7'glyf' and 'loca' must be transformed (or not) together)readerc&g|]\}}|j |Sr{)rQ)rFr7rHs rLrlz,WOFF2FlavorData.__init__...s4!!!"Uu?P!!!!rNrk)r'r* TypeErrorrrUr?rMr3rrrrrrPrkwoff2TransformedTableTagsrO)rBrrFrkrXs rLrMzWOFF2FlavorData.__init__ sf" 8677 7   VWWW ,W  ( ' ' '///***///VWW W ot$$--V-<<<  ;!!&,m&9&9&;&;!!!   ; $ 1D  $ 1D  MDM MDM (WT;N-O-O($($:!  $ 9 !$%6!7!7rNc*tj|Srv)r;r<)rBr]s rL _decompresszWOFF2FlavorData._decompress>s )))rN)NNN)rwrxryFlavorrMrrZr[s@rLr?r?sR F383838383838j*******rNr?ct|dkrtdd}t|ddkrtdttD]q}t|dkrtdt|d}|dd}|dzrtd|d z|d zz}|dzdkr||fcSrtd ) aRead one to five bytes from UIntBase128-encoded input string, and return a tuple containing the decoded integer plus any leftover data. >>> unpackBase128(b'\x3f\x00\x00') == (63, b"\x00\x00") True >>> unpackBase128(b'\x8f\xff\xff\xff\x7f')[0] == 4294967295 True >>> unpackBase128(b'\x80\x80\x3f') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): File "", line 1, in ? TTLibError: UIntBase128 value must not start with leading zeros >>> unpackBase128(b'\x8f\xff\xff\xff\xff\x7f')[0] # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): File "", line 1, in ? TTLibError: UIntBase128-encoded sequence is longer than 5 bytes >>> unpackBase128(b'\x90\x80\x80\x80\x00')[0] # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): File "", line 1, in ? TTLibError: UIntBase128 value exceeds 2**32-1 rz%not enough data to unpack UIntBase128rz3UIntBase128 value must not start with leading zerosrNl|z!UIntBase128 value exceeds 2**32-1rgrz3UIntBase128-encoded sequence is longer than 5 bytes)r0r r r4woff2Base128MaxSize)rFresultrGcodes rLr-r-Bs* 4yyA~~@AAA FtAw4NOOO & ' '    t99>>DEE EtAwABBx J  B@AA AA+$+. 4KA  4<     J K KKrNcF|dksJd}|dkr|dz }|dz}|dk|S)zReturn the length in bytes of a UIntBase128-encoded sequence with value n. >>> base128Size(0) 1 >>> base128Size(24567) 3 >>> base128Size(2**32-1) 5 rrrrgr{)nrs rL base128Sizer%osC 6666 D s((   a s(( KrNc|dks|dkrtdd}t|}t|D]9}|d||z dz zz dz}||dz kr|dz}|tjd |z }:|S) aEncode unsigned integer in range 0 to 2**32-1 (inclusive) to a string of bytes using UIntBase128 variable-length encoding. Produce the shortest possible encoding. >>> packBase128(63) == b"\x3f" True >>> packBase128(2**32-1) == b'\x8f\xff\xff\xff\x7f' True rlz3UIntBase128 format requires 0 <= integer <= 2**32-1rNrgrrrrh)r r%r4rr)r$rFrrGbs rLr1r1s 1uuU NOOO D q>>D 4[[$$ 1q1 % &$ . tax<< IA  C### KrNc0t|dd}|dd}|dkrLt|dkrtdtjd|dd\}|dd}n|dkrIt|dkrtdt|dd}|d z }|dd}nQ|d krIt|dkrtdt|dd}|dz }|dd}n|}||fS) aRead one to three bytes from 255UInt16-encoded input string, and return a tuple containing the decoded integer plus any leftover data. >>> unpack255UShort(bytechr(252))[0] 252 Note that some numbers (e.g. 506) can have multiple encodings: >>> unpack255UShort(struct.pack("BB", 254, 0))[0] 506 >>> unpack255UShort(struct.pack("BB", 255, 253))[0] 506 >>> unpack255UShort(struct.pack("BBB", 253, 1, 250))[0] 506 Nrr#z#not enough data to unpack 255UInt16z>Hrr)r r0r rr1)rFr"r!s rLrrs0 48  D 8D s{{ t99q==BCC CM$RaR11 ABBx  t99>>BCC Cbqb""# ABBx  t99>>BCC Cbqb""# ABBx 4<rNc|dks|dkrtd|dkrtjd|S|dkrtjdd|dz S|d krtjdd |dz Stjd d|S) aEncode unsigned integer in range 0 to 65535 (inclusive) to a bytestring using 255UInt16 variable-length encoding. >>> pack255UShort(252) == b'\xfc' True >>> pack255UShort(506) == b'\xfe\x00' True >>> pack255UShort(762) == b'\xfd\x02\xfa' True riz/255UInt16 format requires 0 <= integer <= 65535r)rr+z>BBrir*z>BH)r rr)r7s rLrrs qyyEFNNJKKK s{{{4''' {5#us{333 {5#us{333{5#u---rNctd|d|t|dd}d|_|t |j||_||ddS) ayCompress OpenType font to WOFF2. Args: input_file: a file path, file or file-like object (open in binary mode) containing an OpenType font (either CFF- or TrueType-flavored). output_file: a file path, file or file-like object where to save the compressed WOFF2 font. transform_tables: Optional[Iterable[str]]: a set of table tags for which to enable preprocessing transformations. By default, only 'glyf' and 'loca' tables are transformed. An empty set means disable all transformations. Processing  => Fr$rN)rFrk reorderTables)r(infor rzr?r@save) input_file output_filetransform_tablesfonts rLrrsHHHjjj++ >??? *5% H H HDDK#)4D    IIkI/////rNctd|d|t|dd}d|_d|_||ddS)aDDecompress WOFF2 font to OpenType font. Args: input_file: a file path, file or file-like object (open in binary mode) containing a compressed WOFF2 font. output_file: a file path, file or file-like object where to save the decompressed OpenType font. r.r/Fr$NTr0)r(r2r rzr@r3)r4r5r7s rLr<r<saHHHjjj++ >??? *5% H H HDDKDOIIkI.....rNcddlddlm}ddlm}Gfddj}Gddj}Gd d j}d tj d }| dd|d| d}| dd}| dd} || fD]J} | d } | dddd| dddd K| d!d"d#$| d!d"d%$| d&d'd(d)$| d&d'd(d*$|} | d+d,d|d-.| d/d,d|d0.|t d1d2h3| t"4t%||} | d5d}|s|dS| d6}| d7}||rd8n|rd9nd:;| d<s|t urd=}n|t"urt-| d!d>5}|d?|d?}dddn #1swxYwYt3|d?ks Jd@|dAkrdBndC}nt5||| d!d|D| d<< |dEi| dS#t6$r }||Yd}~dSd}~wwxYw)Fz#Compress and decompress WOFF2 fontsrN) configLogger)makeOutputFileNameceZdZdfd ZdS)main.._HelpActionNc fd|jD}|D]B}|jD]&\}}t|'C|dS)Nc>g|]}t|j|Sr{) isinstance_SubParsersAction)rFactionargparses rLrlz6main.._HelpAction.__call__.. s<"""fh&@AA""""rN)_actionschoicesrprint format_helpexit) rBparser namespacer option_stringsubparsers_actionssubparsers_actionchoice subparserrCs rL__call__z"main.._HelpAction.__call__ s""""$o"""  &8 3 3!):)B)H)H)J)J33%FI)//1122223 KKMMMMMrNrvrwrxryrP)rCsrL _HelpActionr= s3        rNrRceZdZddZdS)$main.._NoGlyfTransformActionNc>|jddhdS)NrVrX)r6difference_updaterBrIrJrrKs rLrPz-main.._NoGlyfTransformAction.__call__s$  & 8 8&&9I J J J J JrNrvrQr{rNrL_NoGlyfTransformActionrTs. K K K K K KrNrXceZdZddZdS)"main.._HmtxTransformActionNc:|jddSr)r6addrWs rLrPz+main.._HmtxTransformAction.__call__s  & * *6 2 2 2 2 2rNrvrQr{rNrL_HmtxTransformActionrZs( 3 3 3 3 3 3rNr]zfonttools ttLib.woff2F)prog descriptionadd_helpz-hz--helpzshow this help message and exit)rBhelpz sub-commands)titlerz#Compress a TTF or OTF font to WOFF2)r_r<zDecompress a WOFF2 font to OTF)requiredz-vz --verbose store_truezprint more messages to consolez-qz--quietz do not print messages to consoler4INPUTz&the input OpenType font (.ttf or .otf))metavarrazthe input WOFF2 fontz-oz --output-fileOUTPUTzthe output WOFF2 fontzthe output OpenType fontz--no-glyf-transformr6z'Do not transform glyf (and loca) tables)destnargsrBraz--hmtx-transformz/Enable optional transformation for 'hmtx' tablerVrX) subcommandr6)rjrjquietverboseERRORDEBUGINFO)levelr5z.woff2rbr"znot enough datasOTTOz.otfz.ttf) outputDir extensionr{)rC fontToolsr: fontTools.ttxr;rRActionArgumentParsermainrY add_argumentadd_subparsers add_parseradd_mutually_exclusive_groupadd_argument_group set_defaultsrr<vars parse_argspop print_helpopenr-r,r0AssertionErrorr r))argsr:r;rRrXr]rI parser_groupparser_compressparser_decompressrOgrouptransform_groupoptionsrjrkrlrsfrerCs @rLrxrxsdOOO&&&&&&000000       h*   KKKKKKKK33333x333 $ $ $$,%F  h{1R((~(>>L"-- E.O%//"B0&'89   666FF   1      3        5! "" ##     $ ! ""  ' #&88::O   % 6 !   # > !   &)!""j"9996$$T**++G\400J  KK Ekk)$$GLCww%CWWV = !  ! ! II : % %gl+T22 (aq ffQii  ( ( ( ( ( ( ( ( ( ( ( ( ( ( ({##q(((*;((("-"8"8fII ,, ,!3!3 L !TY" " "   W  Qs*?+K66K:=K:M N$M??N__main__rv)MiorrRrQr collectionsrfontTools.miscrfontTools.misc.arrayToolsrfontTools.misc.textToolsrrr r r fontTools.ttLibr r rrrfontTools.ttLib.sfntrrrrrrrrrfontTools.ttLib.tablesrrlogging getLoggerr(r' brotlicffir;r*rr}r2calcsizer/rr*woff2FlagsSizer,r+r r r#rrnrmrrsrr.r_r`rmr?r-r%r1rrrr<rxrwrHr{rNrLrs ######""""""333333JJJJJJJJJJJJJJ                      76666666g/00   #####  JJ   D C+C+C+C+C+*C+C+C+LBBBBB*BBBN $&W%&:;;@D "!"233 'g&'<==((1/B+BB- ,7+,@AA  &$$$G6G6G6G6G6.G6G6G6T#####]]6**###Ll/l/l/l/l/]]6**l/l/l/^ ZZZZZ]]6**ZZZz9*9*9*9*9*n9*9*9*x*L*L*LZ$,)))X....00004///"GGGGT z CHTTVVs07A<;B< BBBBBB