Warning: session_start(): Session cannot be started after headers have already been sent in /home/tvrreohg/public_html/manga.php on line 13
3 2øªjˆÁãM@sZddlmZddlZddlZddlZddlmZddlmZddl m Z ddl m Z m Z mZmZmZddlmZmZmZmZmZddlmZmZmZmZmZmZmZmZm Z dd l!m"Z"m#Z#ddl$Z$e$j%d ƒZ&d Z'y2y ddl(Z)Wne*k rüddl)Z)YnXd Z'Wne*k �rYnXGd d„deƒZ+Gdd„deƒZ,dZ-ej.e-ƒZ/duZ0dQZ1ej.e1ƒZ2dRZ3ej.e3ƒZ4dSZ5dTZ6e2e4dUe6Z7dvZ8dVZ9ej.e9ƒZ:dWZ;dXdY„ZGd^d_„d_edƒƒZ?Gd`da„daedƒƒZ@Gdbdc„dceƒZAddde„ZBdfdg„ZCdhdi„ZDdjdk„ZEdldm„ZFdwdndo„ZGdpdq„ZHdxdrds„ZIeJdtk�rVejKeIƒƒdS)yé)ÚBytesION)Ú OrderedDict)Ússtruct)Ú calcIntBounds)ÚTagÚbytechrÚbyteordÚ bytesjoinÚpad)ÚTTFontÚ TTLibErrorÚgetTableModuleÚ getTableClassÚgetSearchRange) Ú SFNTReaderÚ SFNTWriterÚDirectoryEntryÚWOFFFlavorDataÚsfntDirectoryFormatÚsfntDirectorySizeÚSFNTDirectoryEntryÚsfntDirectoryEntrySizeÚ calcChecksum)Ú ttProgramÚ_g_l_y_fzfontTools.ttLib.woff2FTc@sLeZdZdZddd„Zdd„Zdd „Zdd d „Zd d„Zdd„Z dd„Z d S)Ú WOFF2ReaderÚwoff2réc Cs`tstjdƒtdƒ‚||_t|jjdƒƒ}|dkrÚnextTableOffsetrr8rr.r r<)r=r&r0rjrgr;rBrBrCrD¨s    zWOFF2Writer.__init__cCsb||jkrtd|ƒ‚|dkr0|jd8_dS|jƒ}t|ƒ|_t|jƒ|_||_||j|<dS)z4Associate new entry named 'tag' with raw table data.zcannot rewrite '%s' tableZDSIGrN) r.r r0rrr2ÚgetKnownTagIndexÚflagsr?)r=r2r?rArBrBrCÚ __setitem__Ãs    zWOFF2Writer.__setitem__cCst|jƒ|jkr(td|jt|jƒfƒ‚|jdkr8d}n|jdkrHd}ntdƒ‚|rvd|jjkrvd|jkrv|jd d �|jƒt t |jj ƒƒƒ|_|j ƒ|_ |jƒ}tj|tjd �}t|ƒ|_|jƒ|_|jƒ\|_|_d |_|jƒ}|jjd ƒ|jjt||d d �ƒ|jƒdS)zN All tags must have been specified. Now write the table data and directory. z-wrong number of tables; expected %d, found %dúÚtrueTÚOTTOFz1Not a TrueType or OpenType font (bad sfntVersion)rJr)rK)Úmoder)ÚsizeN)rqrr)r+r.r0r rjr;r[Ú_normaliseGlyfAndLocaÚ_setHeadTransformFlagrÚsortedÚitemsÚ#_calcSFNTChecksumsLengthsAndOffsetsZ totalSfntSizeÚ_transformTablesr6ÚcompressZ MODE_FONTr5Ú_calcTotalSizer4Ú _getVersionÚ majorVersionÚ minorVersionÚreservedÚ_packTableDirectoryr&r(Úwriter Ú_writeFlavorData)r=Z isTrueTypeÚfontDataZcompressedFontÚ directoryrBrBrCÚcloseÕs0          zWOFF2Writer.closercCsN|jdkrdSxdD]}|j|ƒqW||jd_xdD]}|j|ƒq8WdS) z« Recompile glyf and loca tables, aligning glyph offsets to multiples of 'padding' size. Update the head table's 'indexToLocFormat' accordingly while compiling loca. rsNrXrZrLrJ)rXrZrLrJ)rJrL)rjr\r<rKÚ _compileTable)r=rKr2rBrBrCrvs    z!WOFF2Writer._normaliseGlyfAndLocacCs,|jdƒ|jdjdO_|jdƒdS)z‡ Set bit 11 of 'head' table flags to indicate that the font has undergone a lossless modifying transform. Re-compile head table data.rZré Ni)r\r<rorˆ)r=rBrBrCrws z!WOFF2Writer._setHeadTransformFlagcCs’t|ƒ}||jkrtd|ƒ‚|jj|ƒr.dS|j|j}|dkrHt}n$|dkrVt}n|dkrdt}nt |ƒ}||ƒ}||jj|<|j ||jƒdS)zB Fetch table data, decompile it, and store it inside self.ttFont. zmissing required table: %sNrLrJrM) rr.r r<r_r?rRrSr]rr`)r=r2r?rarbrBrBrCr\s      zWOFF2Writer._decompileTablecCs|j|j|jƒ|j|_dS)z5 Compile table and store it in its 'data' attribute. N)r<rUr.r?)r=r2rBrBrCrˆ0szWOFF2Writer._compileTablecCsŒttt|jƒ}xt|jjƒD]f\}}|j}||_t|ƒ|_|dkrht|dd…d|dd…ƒ|_ n t|ƒ|_ ||jdd@7}qW|S)z• Compute the 'original' SFNT checksums, lengths and offsets for checksum adjustment calculation. Return the total size of the uncompressed font. rZNésé ééüÿÿÿ) rrr+r.ryr?Ú origOffsetrWrÚcheckSum)r=r3r2rAr?rBrBrCrz4s $ z/WOFF2Writer._calcSFNTChecksumsLengthsAndOffsetscCs”|jj}xt|jjƒD]f\}}d}||kr@|j|ƒ}|dk r@d|_|dkrT|j}d|_|j|_|j |j |ƒ|j|j 7_qW|j ƒ|j j ƒ}|S)zReturn transformed font data.NTF)r;r[r.ryÚtransformTablerFr?rmr3ZsaveDatar8r4ÚwriteMasterChecksumÚgetvalue)r=r[r2rAr?r…rBrBrCr{Ds   zWOFF2Writer._transformTablescCsœ|dkrd}nŠ|dkrFxd D]}|j|ƒqW|jd}|j|jƒ}nR|dkrŒd|jkr\dSxd D]}|j|ƒqbW|jd}|j|jƒ}n td |ƒ‚|S) zŒReturn transformed table data, or None if some pre-conditions aren't met -- in which case, the non-transformed table data will be used. rLórJrXrZrMNrYz#Transform for table '%s' is unknown)rXrZrLrJ)rXrZrYrLrJrM)r\r<Ú transformr.r )r=r2r?rVr^rBrBrCr�Xs       zWOFF2Writer.transformTablec Cst|jjƒƒ}g}x*tt|ƒƒD]}|j|j||jƒq Wt|jdƒ\|_ |_ |_ t j t|ƒ}t|jjƒƒ}xB|D]:\}}tƒ}|j|_|j|_|j|_|j|_||jƒ}qvWtt|jƒt} | t|ƒksÖt‚|jt|ƒƒt|ƒd@} d| d@} | S)zCalculate checkSumAdjustment.élÿÿlº/ac)Úlistr.Úkeysr/r+Úappendr�rr0Z searchRangeZ entrySelectorZ rangeShiftrÚpackrrxryrr2rŽr3rWr4ÚtoStringrrÚAssertionErrorrÚsum) r=ÚtagsZ checksumsr@r†r.r2rAZ sfntEntryZ directory_endZchecksumÚchecksumadjustmentrBrBrCÚ_calcMasterChecksumns(   zWOFF2Writer._calcMasterChecksumcCs8|jƒ}|jj|jdjdƒ|jjtjd|ƒƒdS)z0Write checkSumAdjustment to the transformBuffer.rZrŠz>LN)rŸr8r(r.r3rƒÚstructr™)r=ržrBrBrCr‘ŠszWOFF2Writer.writeMasterChecksumcCsN|j}x"|jjƒD]}|t|jƒƒ7}qW||j7}|dd@}|j|ƒ}|S)zLCalculate total size of WOFF2 font, including any meta- and/or private data.rŒr�)rlr.Úvaluesr+ršr5Ú_calcFlavorDataOffsetsAndSize)r=r3rArBrBrCr}�s   zWOFF2Writer._calcTotalSizecCs¦|}|j}|jrNt|jƒ|_||_tj|jtjd�|_t|jƒ|_ ||j 7}nd|_|_ |_d|_|j r–|dd@}||_ t|j ƒ|_ ||j 7}n d|_ |_ |S)z@Calculate offsets and lengths for any meta- and/or private data.)rtrr“rŒr�) r;ÚmetaDatar+ZmetaOrigLengthÚ metaOffsetr6r|Z MODE_TEXTÚcompressedMetaDataZ metaLengthÚprivDataÚ privOffsetZ privLength)r=Ústartr3r?rBrBrCr¢šs$       z)WOFF2Writer._calcFlavorDataOffsetsAndSizecCsT|j}|jdk r&|jdk r&|j|jfSd|jkrLtjd|jdjdd…ƒSdSdS)z;Return the WOFF2 font's (majorVersion, minorVersion) tuple.NrZz>HHrrŠr)rr)r;rr€r.r r,r?)r=r?rBrBrCr~²s   zWOFF2Writer._getVersioncCs2tj|j|ƒ}x|jjƒD]}||jƒ}qW|S)z"Return WOFF2 table directory data.)rr™rkr.r¡rš)r=r†rArBrBrCr‚¾szWOFF2Writer._packTableDirectorycCsŠ|j}|jj}|r"|r"t|dd�}|rT|jj|jƒ|jjƒ|jksHt‚|jj |ƒ|r†|jj|j ƒ|jjƒ|j kszt‚|jj |ƒdS)z # 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 ÚcmaprZrYrMrXÚnameúOS/2Úpostúcvt ÚfpgmrJrLÚprepúCFF ÚVORGÚEBDTÚEBLCÚgaspÚhdmxÚkernÚLTSHÚPCLTÚVDMXÚvheaÚvmtxÚBASEÚGDEFÚGPOSÚGSUBÚEBSCÚJSTFÚMATHÚCBDTÚCBLCÚCOLRÚCPALúSVG ÚsbixÚacntÚavarÚbdatÚblocÚbslnÚcvarÚfdscÚfeatÚfmtxÚfvarÚgvarÚhstyÚjustÚlcarÚmortÚmorxÚopbdÚpropÚtrakÚZapfÚSilfÚGlatÚGlocÚFeatÚSillz5 > # big endian flags: B # table type and flags z5 > # big endian tag: 4s # 4-byte tag (optional) é?éraN > # big endian version: L # = 0x00000000 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 cCs*x$tttƒƒD]}|t|kr|SqWtS)zEReturn index of 'tag' in woff2KnownTags list. Return 63 if not found.)r/r+Úwoff2KnownTagsÚwoff2UnknownTagIndex)r2r@rBrBrCrn%s rnc@sXeZdZdd„Zdd„Zdd„Zedd„ƒZejd d„ƒZed d „ƒZ e jd d „ƒZ d S)r)cCs>|jƒ}|jtƒ}|j|ƒ}t|ƒt|ƒ}|j||ƒdS)N)r9r'Úwoff2DirectoryEntryMaxSizeÚ fromStringr+r()r=r&Úposr?ÚleftÚconsumedrBrBrCr1/s   zWOFF2DirectoryEntry.fromFilecCsÂt|ƒdkrtdƒ‚tjt||ƒ\}}|jd@dkr\t|ƒtkrHtdƒ‚tjt||ƒ\}}nt|jd@|_ t |j ƒ|_ t |ƒ\|_ }|j |_ |jr¾t |ƒ\|_ }|j dkr¾|j dkr¾tdƒ‚|S)Nrz)can't read table 'flags': not enough datarãz'can't read table 'tag': not enough datarLrz1the transformLength of the 'loca' table must be 0)r+r rÚunpack2Úwoff2FlagsFormatroÚwoff2UnknownTagSizeÚwoff2UnknownTagFormatrår2rÚ unpackBase128rWr4rF)r=r?ÚdummyrBrBrCrè6s"   zWOFF2DirectoryEntry.fromStringcCsTt|jƒ}|jd@dkr.|tjd|jjƒƒ7}|t|jƒ7}|jrP|t|j ƒ7}|S)Nrãz>4s) rror r™r2ÚtobytesÚ packBase128rWrFr4)r=r?rBrBrCršMs zWOFF2DirectoryEntry.toStringcCs |jd?S)z~Return bits 6-7 of table entry's flags, which indicate the preprocessing transformation version number (between 0 and 3). é)ro)r=rBrBrCÚtransformVersionVsz$WOFF2DirectoryEntry.transformVersioncCs2d|kodknst‚|j|d>O_dS)NrrŒrô)r›ro)r=ÚvaluerBrBrCrõ]scCs"|jdkr|jdkS|jdkSdS)zCReturn True if the table has any transformation, else return False.rJrLrŒrN>rJrL)r2rõ)r=rBrBrCrFbs  zWOFF2DirectoryEntry.transformedcCs(|jdkr|sdnd|_n t|ƒ|_dS)NrJrLrŒr>rJrL)r2rõÚint)r=Z booleanValuerBrBrCrFns N) rdrerfr1rèršÚpropertyrõÚsetterrFrBrBrBrCr)-s  r)cs*eZdZdZddd„Z‡fdd„Z‡ZS)rRz‚Same as parent class. The only difference is that it attempts to preserve the 'indexFormat' as encoded in the WOFF2 glyf table. NcCst|pdƒ|_dS)NrL)rÚtableTag)r=r2rBrBrCrD~szWOFF2LocaTable.__init__c süyt|jƒ}Wn"tk r0|jgƒd}YnXd|krèt|ddƒrè|dj}|dkr¾|dkrjtdƒ‚tdd„|jDƒƒs†tdƒ‚tjd ƒ}x:t t |jƒƒD]}|j |j|d ƒq Wntjd |jƒ}t j d krÞ|jƒ|jƒ}ntt|ƒj|ƒ}|S) NrrJÚ indexFormatiz,indexFormat is 0 but local offsets > 0x20000css|]}|ddkVqdS)rrNrB)Ú.0ÚlrBrBrCú �sz)WOFF2LocaTable.compile..z5indexFormat is 0 but local offsets not multiples of 2ÚHrÚIÚbig)ÚmaxÚ locationsÚAttributeErrorÚsetrErûr ÚallÚarrayr/r+r˜ÚsysÚ byteorderÚbyteswapròÚsuperrRrU)r=r<Z max_locationrûrr@r?)Ú __class__rBrCrU�s*      zWOFF2LocaTable.compile)N)rdrerfÚ__doc__rDrUÚ __classcell__rBrB)r rCrRys rRc@sŽeZdZdZd(Zd)d d „Zd d „Zdd„Zdd„Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd S)*rSz1Decoder/Encoder for WOFF2 'glyf' table transform.ÚnContourStreamÚ nPointsStreamÚ flagStreamÚ glyphStreamÚcompositeStreamÚ bboxStreamÚinstructionStreamNcCst|pdƒ|_dS)NrJ)rrú)r=r2rBrBrCrD£szWOFF2GlyfTable.__init__c CsÔt|ƒ}|tkrtdƒ‚tjt||ƒ\}}t}xD|jD]:}t||dƒ}t|||d|…ƒ||d…}||7}q6W||krŒtd||fƒ‚|j dd?d>}|j d|…} t j d| ƒ|_ |j |d…|_ t j d |j ƒ|_ tjd krî|j jƒt|j ƒ|j k�st‚d |k�r|j|d _y|jƒ|_Wnd|_YnX|jdk�rpd g|_|jjd d„td|j ƒDƒƒn*t|jƒ|j k�rštdt|jƒ|j fƒ‚i} |_x*t|jƒD]\} } |j| ƒ} | | | <�q°WdS)z$ Decompile transformed 'glyf' data. znot enough 'glyf' dataÚSizeNzJincorrect size of transformed 'glyf' table: expected %d, received %d bytesérärÚBÚhrrZz.notdefcSsg|] }d|‘qS)z glyph%.5drB)rür@rBrBrCú Ësz.WOFF2GlyfTable.reconstruct..rz2incorrect glyphOrder: expected %d glyphs, found %d)r+Úwoff2GlyfTableFormatSizer rrìÚwoff2GlyfTableFormatÚ subStreamsÚgetattrÚsetattrÚ numGlyphsrrÚ bboxBitmaprrr r r›rûÚindexToLocFormatÚ getGlyphOrderÚ glyphOrderÚextendr/ÚglyphsÚ enumerateÚ _decodeGlyph)r=r?r<Z inputDataSizerñr3ÚstreamruÚbboxBitmapSizer!r&ÚglyphIDÚ glyphNameÚglyphrBrBrCrT¦sN            zWOFF2GlyfTable.reconstructcstˆjƒˆ_tˆjƒˆjks t‚d|kr4ˆj|d_|djˆ_xˆjD]}tˆ|dƒqHWˆjdd?d>}t j ddg|ƒˆ_ xt ˆjƒD]}ˆj |ƒqŽWˆj j ƒˆjˆ_x(ˆjD]}tˆ|d ttˆ|ƒƒƒqºWdˆ_tjtˆƒ}|t‡fd d „ˆjDƒƒ7}|S) z Return transformed 'glyf' data rXrZr“rrärrrrcsg|]}tˆ|ƒ‘qSrB)r)rüÚs)r=rBrCrìsz,WOFF2GlyfTable.transform..)r+r&r r$r›r"rûrrrr!r/Ú _encodeGlyphròrrÚversionrr™rr )r=r<r)r*r+r?rB)r=rCr”×s$      zWOFF2GlyfTable.transformcCsTtdƒjƒ}|j||_|jdkr&|S|jƒr:|j|ƒn |j|ƒ|j||ƒ|S)NrJr)r ZGlyphrÚnumberOfContoursÚ isCompositeÚ_decodeComponentsÚ_decodeCoordinatesÚ _decodeBBox)r=r+r-rBrBrCr(ïs      zWOFF2GlyfTable._decodeGlyphcCsh|j}g|_d}d}x:|rNtdƒjƒ}|j||ƒ\}}}||B}|jj|ƒqW||_|rd|j|ƒdS)NrrrJ)rÚ componentsr ZGlyphComponentr`r˜Ú_decodeInstructions)r=r-r?ÚmoreÚhaveInstructionsÚ componentZ haveInstrrBrBrCr3ûs z WOFF2GlyfTable._decodeComponentscCsd|j}g}d}x0t|jƒD]"}t|ƒ\}}||7}|j|ƒqW||_||_|j|ƒ|j|ƒdS)Nrrc)rr/r1Úunpack255UShortr˜ÚendPtsOfContoursÚ_decodeTripletsr7)r=r-r?r<ÚendPointr@Ú ptsOfContourrBrBrCr4 s  z!WOFF2GlyfTable._decodeCoordinatescCsN|j}|j}t|ƒ\}}tjƒ|_|jj|d|…ƒ||_||d…|_dS)N)rrr;rZProgramÚprogramZ fromBytecode)r=r-rrZinstructionLengthrBrBrCr7s  z"WOFF2GlyfTable._decodeInstructionscCsbt|j|d?d|d@?@ƒ}|jƒr8| r8td|ƒ‚|rTtjt|j|ƒ\}|_n |j|ƒdS)NrŒé€éz%no bbox values for composite glyph %d) Úboolr!r2r rrìÚ bboxFormatrZ recalcBounds)r=r+r-ZhaveBBoxrñrBrBrCr5s  zWOFF2GlyfTable._decodeBBoxcCsdd„}|jdd}|}|t|jƒkr0tdƒ‚|jd|…}|j|d…|_tjd|ƒ}tjd|jƒ}t|ƒ}||ks|t‚d} d} tdƒjj |ƒ|_ tjdƒ|_ d} �xPt |ƒD�]B} || } t | d?ƒ }| d M} | d kräd}n"| d kròd }n| d k�rd}nd}| ||k�st‚| dk�rDd}|| | d@d>|| ƒ}�n|| dk�rt|| | dd@d>|| ƒ}d}�nL| d k�rÌ| d}|| }|| d|d@|d?ƒ}|| d?d|d@d >|d@ƒ}nô| d k�r(| d }|| d|dd>|| ƒ}|| d?d|dd ?d>|| dƒ}n˜| d k�r||| d}|| || d>|d?ƒ}|| d?|d@d>|| d ƒ}nD|| || d>|| dƒ}|| d?|| d d>|| dƒ}| |7} | |7} | |7} | | f|j | <|j jt|ƒƒq²W| }|j|d…|_dS)NcSs*d|kr|dkstdƒ‚|d@r$|S| S)Nrizinteger overflowr)r›)ÚflagZbasevalrBrBrCÚwithSign*sz0WOFF2GlyfTable._decodeTriplets..withSignrznot enough 'flagStream' datarrrJrBééTéxré|rŒré ééé0r‹érŠrc)r<r+rr rrr›r ZGlyphCoordinatesÚzerosÚ coordinatesror/rCr˜r÷)r=r-rFZnPointsZflagSizeZ flagsDataroÚtripletsZ nTripletsÚxÚyZ tripletIndexr@rEÚonCurveZnBytesZdxZdyZb0Zb1Zb2Z bytesConsumedrBrBrCr=(sx       $ $  zWOFF2GlyfTable._decodeTripletscCsf|j|ƒ}||}|jtjd|jƒ7_|jdkr8dS|jƒrL|j|ƒn |j|ƒ|j||ƒdS)Nz>hr) Z getGlyphNamerr r™r1r2Ú_encodeComponentsÚ_encodeCoordinatesÚ _encodeBBox)r=r+r,r-rBrBrCr/ns    zWOFF2GlyfTable._encodeGlyphcCsxt|jƒd}d}d}xNtt|jƒƒD]<}||kr@t|dƒ}d}|j|}|j|j|||ƒ7_q&W|rt|j|ƒdS)Nrrr@)r+r6r/rErrUÚ_encodeInstructions)r=r-Z lastcomponentr8r9r@r:rBrBrCrVzs  z WOFF2GlyfTable._encodeComponentscCsJd}x,|jD]"}||}|jt|ƒ7_|}q W|j|ƒ|j|ƒdS)Nrrc)r<rÚ pack255UShortÚ_encodeTripletsrY)r=r-Z lastEndPointr>r?rBrBrCrW‡s  z!WOFF2GlyfTable._encodeCoordinatescCs2|jjƒ}|jtt|ƒƒ7_|j|7_dS)N)r@Z getBytecoderrZr+r)r=r-Z instructionsrBrBrCrY�s z"WOFF2GlyfTable._encodeInstructionscCs||jdkstdƒ‚|jƒsD|j|j|j|jf}t|jƒ}||krDdS|j |d?d|d@?O<|j t j t |ƒ7_ dS)Nrzempty glyph has no bboxrŒrArB)r1r›r2ÚxMinZyMinZxMaxZyMaxrrQr!rrr™rD)r=r+r-Z currentBBoxZcalculatedBBoxrBrBrCrX•s zWOFF2GlyfTable._encodeBBoxcCsÞt|jƒt|jƒkst‚|jjƒ}|jƒtjdƒ}tjdƒ}�xttt|ƒƒD�]b}|j|tj @}||\}}t |ƒ} t |ƒ} |rˆdnd} |dkr˜dnd} |dkr¨dnd} | d| }|dkrò| dkrò|j | | d@d?| ƒ|j | d @ƒqN|dk�r4| dk�r4|j | d | d@d?| ƒ|j | d @ƒqN| d k�rš| d k�rš|j | d | dd @| dd @d?|ƒ|j | dd@d>| dd@BƒqN| dk�r | dk�r |j | dd| dd@d?| dd@d?|ƒ|j | dd @ƒ|j | dd @ƒqN| dk�rh| dk�rh|j | d|ƒ|j | d?ƒ|j | d@d>| d?Bƒ|j | d @ƒqN|j | d|ƒ|j | d?ƒ|j | d @ƒ|j | d?ƒ|j | d @ƒqNW|j |j ƒ7_ |j|j ƒ7_dS)NrrrArriirBéÿrKéArMrNrOrirHr‹irŠrôirIrJ)r+rQror›ÚcopyZabsoluteToRelativerr/rZ flagOnCurveÚabsr˜rròr)r=r-rQrorRr@rUrSrTZabsXZabsYZ onCurveBitZxSignBitZySignBitZ xySignBitsrBrBrCr[¡sN      .$6zWOFF2GlyfTable._encodeTriplets)rrrrrrr)N)rdrerfr rrDrTr”r(r3r4r7r5r=r/rVrWrYrXr[rBrBrBrCrSœs$ 1    F    rSc@s&eZdZddd„Zdd„Zdd„ZdS) r]NcCst|pdƒ|_dS)NrM)rrú)r=r2rBrBrCrDÑszWOFF2HmtxTable.__init__cCsÐtjd|dd…ƒ\}|dd…}|d@dkrBréürz#Bits 2-7 of '%s' flags are reservedrz?either bits 0 or 1 (or both) must set in transformed '%s' flagsrJrYrÿrrr\ztoo much '%s' table datarc)r r,r rúr$r+Úminr÷ÚnumberOfHMetricsr›rrr r r'rr˜Úmetricsr/)r=r?r<roÚ hasLsbArrayÚhasLeftSideBearingArrayrVZ headerTabler$r rcÚadvanceWidthArrayÚlsbArrayr@r,r-r\ZnumberOfSideBearingsÚleftSideBearingArrayZ advanceWidthÚlsbZ lastAdvancerBrBrCrTÔst               zWOFF2HmtxTable.reconstructcsº|jƒ‰|d}|d}|j‰d}x@tˆƒD]4}ˆ|}ˆj|d}|t||ddƒkr,d}Pq,Wd}xFtˆtˆƒƒD]4}ˆ|}ˆj|d}|t||ddƒkrxd}PqxW|r¼|r¼dSd} |sÌ| dO} |sØ| dO} tjd| ƒ} tjd ‡‡fd d „t ˆƒDƒƒ} t j d k�r| j ƒ| | j ƒ7} |�rjtjd ‡‡fdd „t ˆƒDƒƒ} t j d k�r^| j ƒ| | j ƒ7} |�r¶tjd ‡‡fdd „tˆtˆƒƒDƒƒ} t j d k�rª| j ƒ| | j ƒ7} | S)NrJrYFrr\rTz>Brÿcs&g|]\}}|ˆkrˆj|d‘qS)r)rd)rür@r,)rcr=rBrCrHsz,WOFF2HmtxTable.transform..rrcs&g|]\}}|ˆkrˆj|d‘qS)r)rd)rür@r,)rcr=rBrCrUscsg|]}ˆjˆ|d‘qS)r)rd)rür@)r$r=rBrCrbsrr)r#rcr/rdrr+r r™rr'rr r rò)r=r<rJrYrer@r,rjrfror?rgrhrirB)r$rcr=rCr”sd          zWOFF2HmtxTable.transform)N)rdrerfrDrTr”rBrBrBrCr]Ïs Jr]cs*eZdZdZd‡fdd„ Zdd„Z‡ZS)r:rNcsæts tdƒ‚|dk r4|dk r$tdƒ‚|dk r4tdƒ‚|dk rdd|krLd|ks\d|krdd|krdtdƒ‚tt|ƒj|d�|r�d d „|jjƒDƒ}n<|rÌ|j |_ |j |_ |j |_ |j |_ |dkrÌt |d ƒrÌ|j}|dkrØ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. zNo module named brotliNz4'reader' and 'data' arguments are mutually exclusivezA'reader' and 'transformedTables' arguments are mutually exclusiverJrLz7'glyf' and 'loca' must be transformed (or not) together)ÚreadercSsg|]\}}|jr|‘qSrB)rF)rür2rArBrBrCr™sz,WOFF2FlavorData.__init__..r[)r"r%Ú TypeErrorÚ ValueErrorr r:rDr.ryrr€r£r¦rEr[Úwoff2TransformedTableTagsr)r=rkr?r[)r rBrCrDqs8zWOFF2FlavorData.__init__cCs tj|ƒS)N)r6r7)r=rQrBrBrCÚ _decompressªszWOFF2FlavorData._decompress)NNN)rdrerfZFlavorrDrorrBrB)r rCr:ms9r:cCs®t|ƒdkrtdƒ‚d}t|dƒdkr0tdƒ‚xpttƒD]d}t|ƒdkrRtdƒ‚t|dƒ}|dd…}|d@rztdƒ‚|d >|d @B}|d@dkr:||fSq:Wtd ƒ‚dS) a€ Read 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 UIntBase128rAz3UIntBase128 value must not start with leading zerosrNl|z!UIntBase128 value exceeds 2**32-1rBrGz3UIntBase128-encoded sequence is longer than 5 bytes)r+r rr/Úwoff2Base128MaxSize)r?Úresultr@ÚcoderBrBrCrð®s       rðcCs2|dks t‚d}x|dkr,|d7}|dL}qW|S)z� Return the length in bytes of a UIntBase128-encoded sequence with value n. >>> base128Size(0) 1 >>> base128Size(24567) 3 >>> base128Size(2**32-1) 5 rrrArB)r›)ÚnrurBrBrCÚ base128SizeÛs   rtcCsv|dks|d krtdƒ‚d}t|ƒ}xLt|ƒD]@}|d||d?d@}||dkr^|d O}|tjd |ƒ7}q.W|S) a  Encode 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 rré z3UIntBase128 format requires 0 <= integer <= 2**32-1r“rBrrGrArl)r rtr/r r™)rsr?rur@ÚbrBrBrCróís  rócCsìt|dd…ƒ}|dd…}|dkr\t|ƒdkr8tdƒ‚tjd|dd…ƒ\}|dd…}nˆ|dkržt|ƒdkrxtdƒ‚t|dd…ƒ}|d 7}|dd…}nF|d kràt|ƒdkrºtdƒ‚t|dd…ƒ}|d7}|dd…}n|}||fS) a§ Read 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 Nréýrz#not enough data to unpack 255UInt16z>Héþriúr])rr+r r r,)r?rrrqrBrBrCr;s*    r;cCsr|dks|dkrtdƒ‚|dkr,tjd|ƒS|dkrFtjdd|dƒS|d kr`tjdd |dƒStjd d|ƒSd S) zý Encode 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 riÿÿz/255UInt16 format requires 0 <= integer <= 65535rwz>Biúz>BBr]iúrxz>BHN)r r r™)rörBrBrCrZ0s  rZcCsPtjd||fƒt|ddd�}d|_|dk r>t|j|d�|_|j|dd�dS)aCompress 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. zProcessing %s => %sF)r r!rN)r?r[)Ú reorderTables)r#Úinfor rgr:r;Úsave)Ú input_fileÚ output_fileÚtransform_tablesÚfontrBrBrCr|Hs r|cCs>tjd||fƒt|ddd�}d|_d|_|j|dd�dS)aDecompress 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. zProcessing %s => %sF)r r!NT)ry)r#rzr rgr;r{)r|r}rrBrBrCr7bs r7cs´ddl‰ddlm}ddlm}G‡fdd„dˆjƒ}Gdd„dˆjƒ}Gd d „d ˆjƒ}ˆjd tj d d �}|j dd|dd�|j dd�}|j ddd�}|j ddd�} x@|| fD]4} | j d d�} | j ddddd�| j dddd d�q°W|j d!d"d#d$�| j d!d"d%d$�|j d&d'd(d)d$�| j d&d'd(d*d$�|jƒ} | j d+d,d|d-d.�| j d/d,d|d0d.�|jtd1d2hd3�| jtd4�t|j|ƒƒ} | jd5dƒ}|�s¦|jƒdS| jd6ƒ}| jd7ƒ}||�rÆd8n |�rÐd9nd:d;�| d<�sr|tk�ròd=}nj|tk�rTt| d!d>ƒ�}|jd?ƒ|jd?ƒ}WdQRXt|ƒd?k�s@td@ƒ‚|dAk�rNdBndC}nt|ƒ‚|| d!d|dD�| d<<y|f| ŽWn.tk �r®}z|j|ƒWYdd}~XnXdS)Ez#Compress and decompress WOFF2 fontsrN)Ú configLogger)ÚmakeOutputFileNamecseZdZd‡fdd„ ZdS)zmain.._HelpActionNc sR‡fdd„|jDƒ}x0|D](}x"|jjƒD]\}}t|jƒƒq*WqW|jƒdS)Ncsg|]}t|ˆjƒr|‘qSrB)Ú isinstanceZ_SubParsersAction)rüÚaction)ÚargparserBrCr}sz6main.._HelpAction.__call__..)Z_actionsÚchoicesryÚprintÚ format_helpÚexit) r=ÚparserÚ namespacer¡Ú option_stringZsubparsers_actionsZsubparsers_actionÚchoiceÚ subparser)r„rBrCÚ__call__{s  z"main.._HelpAction.__call__)N)rdrerfrŽrB)r„rBrCÚ _HelpActionysr�c@seZdZddd„ZdS)z$main.._NoGlyfTransformActionNcSs|jjddhƒdS)NrJrL)r~Údifference_update)r=r‰rŠr¡r‹rBrBrCrŽ…sz-main.._NoGlyfTransformAction.__call__)N)rdrerfrŽrBrBrBrCÚ_NoGlyfTransformAction„sr‘c@seZdZddd„ZdS)z"main.._HmtxTransformActionNcSs|jjdƒdS)NrM)r~Úadd)r=r‰rŠr¡r‹rBrBrCrމsz+main.._HmtxTransformAction.__call__)N)rdrerfrŽrBrBrBrCÚ_HmtxTransformActionˆsr“zfonttools ttLib.woff2F)ÚprogÚ descriptionÚadd_helpz-hz--helpzshow this help message and exit)rƒÚhelpz sub-commands)Útitler|z#Compress a TTF or OTF font to WOFF2)r•r7zDecompress a WOFF2 font to OTF)Úrequiredz-vz --verboseÚ store_truezprint more messages to consolez-qz--quietz do not print messages to consoler|ZINPUTz&the input OpenType font (.ttf or .otf))Úmetavarr—zthe input WOFF2 fontz-oz --output-fileZOUTPUTzthe output WOFF2 fontzthe output OpenType fontz--no-glyf-transformr~z'Do not transform glyf (and loca) tables)ÚdestÚnargsrƒr—z--hmtx-transformz/Enable optional transformation for 'hmtx' tablerJrL)Ú subcommandr~)ržržÚquietÚverboseÚERRORÚDEBUGÚINFO)Úlevelr}z.woff2Úrbrznot enough datasOTTOz.otfz.ttf)Z outputDirÚ extension)r„Z fontToolsr€Z fontTools.ttxr�r�ZActionÚArgumentParserÚmainr Ú add_argumentZadd_subparsersZ add_parserÚadd_mutually_exclusive_groupÚadd_argument_groupÚ set_defaultsr|r7ÚvarsÚ parse_argsÚpopÚ print_helpÚopenr(r'r+r›r r$)Úargsr€r�r�r‘r“r‰Z parser_groupZparser_compressZparser_decompressr�ÚgroupZtransform_groupÚoptionsržrŸr r¦ÚfrjÚerB)r„rCr¨ss²                r¨Ú__main__)?rªrZrYrMrXr«r¬r­r®r¯rJrLr°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ËrÌrÍrÎrÏrÐrÑrÒrÓrÔrÕrÖr×rØrÙrÚrÛrÜrÝrÞrßràrárâ)rJrL)N)N)LÚiorrrr Ú collectionsrZfontTools.miscrZfontTools.misc.arrayToolsrZfontTools.misc.textToolsrrrr r ZfontTools.ttLibr r r rrZfontTools.ttLib.sfntrrrrrrrrrZfontTools.ttLib.tablesrrÚloggingÚ getLoggerr#r"Z brotlicffir6r%rrhr-Úcalcsizer*råríZwoff2FlagsSizerïrîrærprçrnrrrDrnr)rRrSr]r:rðrtrór;rZr|r7r¨rdrˆrBrBrBrCÚs„    ,  H    L#5A-,