)Ej *ddlZddlmZddlmZddlmZddlmZm Z ddl m Z ddl Z dZ gdZd Zegd Zd ZGd d eZGddeZGddeZGddeZGddeZGddeZGddeZGddeZGddeZGddeZGd d!eZGd"d#eZGd$d%eZ Gd&d'eZ!Gd(d)eZ"Gd*d+eZ#Gd,d-eZ$Gd.d/eZ%Gd0d1eZ&Gd2d3eZ'Gd4d5eZ(Gd6d7eZ)Gd8d9eZ*Gd:d;eZ+Gd<d=eZ,Gd>d?eZ-Gd@dAeZ.GdBdCeZ/GdDdEeZ0GdFdGeZ1GdHdIeZ2GdJdKeZ3GdLdMeZ4GdNdOeZ5GdPdQeZ6GdRdSeZ7GdTdUeZ8GdVdWeZ9GdXdYeZ:GdZd[eZ;Gd\d]eZ<Gd^d_eZ=Gd`daeZ>GdbdceZ?GdddeeZ@GdfdgeZAGdhdieZBGdjdkeZCGdldmeZDGdndoeZEGdpdqeZFdrZGGdsdteZHGdudveHZIGdwdxeHZJGdydzeZKGd{d|eHZLGd}d~eZMGddeZNGddeZOGddeZPGddeZQGddeZRGddeZSGddeZTGddeZUGddeZVGddeZWGddeZXdS)N)FeatureLibError)FeatureLibLocation) getEncoding)byteordtobytes) OrderedDictz )BElement FeatureFileComment GlyphName GlyphClassGlyphClassName MarkClassNameAnonymousBlockBlock FeatureBlock NestedBlock LookupBlockGlyphClassDefinitionGlyphClassDefStatement MarkClassMarkClassDefinitionAlternateSubstStatementAnchorAnchorDefinitionAttachStatementAxisValueLocationStatementBaseAxisCVParametersNameStatementChainContextPosStatementChainContextSubstStatementCharacterStatementConditionsetStatementCursivePosStatementElidedFallbackNameElidedFallbackNameID ExpressionFeatureNameStatementFeatureReferenceStatementFontRevisionStatement HheaFieldIgnorePosStatementIgnoreSubstStatementIncludeStatementLanguageStatementLanguageSystemStatementLigatureCaretByIndexStatementLigatureCaretByPosStatementLigatureSubstStatementLookupFlagStatementLookupReferenceStatementMarkBasePosStatementMarkLigPosStatementMarkMarkPosStatementMultipleSubstStatement NameRecordOS2FieldPairPosStatement ReverseChainSingleSubstStatementScriptStatementSinglePosStatementSingleSubstStatementSizeParameters StatementSTATAxisValueStatementSTATDesignAxisStatementSTATNameStatementSubtableStatement TableBlock ValueRecordValueRecordDefinition VheaFieldcN|dSddd|DzS)Nz z , c3 K|] }d|zV dS)z%d %dN).0ts FC:\PYTHON\MyICR_Suite\python\Lib\site-packages\fontTools/feaLib/ast.py z!deviceToString..Us&(E(E1(E(E(E(E(E(E)join)devices rQdeviceToStringrVQs2 ~tyy(E(Ef(E(E(EEEEErS)4anchor anchordefanon anonymousbycontourcursiverUenum enumerate excludedflt exclude_dfltfeaturefromignoreignorebaseglyphsignoreligatures ignoremarksinclude includedflt include_dfltlanguagelanguagesystemlookup lookupflagmarkmarkattachmenttype markclassnameidnull parameterspospositionrequired righttoleft reversesubrsubscriptsub substitutesubtabletableusemarkfilteringset useextensionvaluerecorddefbasegdefheadhheanamevheavmtxc:t|dr|St|trAt |dkr.t|ddzt|dzS|t vrd|zS|S)NasFearz - \)hasattrr isinstancetuplelenlower fea_keywords)gs rQrrsq'wwyy Au  #a&&A++QqT{{U"U1Q4[[00 l " "axrSc.eZdZdZddZdZd dZdZdS) r z8A base class representing "something" in a feature file.NcT|rt|ts t|}||_dSN)rrlocationselfrs rQ__init__zElement.__init__s1  5Jx1CDD 5)84H  rScdSrrNrbuilders rQbuildz Element.builds rSct)zReturns this element as a string of feature code. For block-type elements (such as :class:`FeatureBlock`), the `indent` string is added to the start of each line in the output.)NotImplementedErrorrindents rQrz Element.asFeas "!rSc*|Srrrs rQ__str__zElement.__str__szz||rSrr)__name__ __module__ __qualname____doc__rrrrrNrSrQr r s`BB!!!!    """" rSr ceZdZdS)rBNrrrrNrSrQrBrBDrSrBceZdZdS)r'NrrNrSrQr'r'rrSr'c,eZdZdZdfd ZddZxZS)r zA comment in a feature file.Ncftt||||_dSr)superr rtext)rrr __class__s rQrzComment.__init__s, gt%%h/// rSrc|jSr)rrs rQrz Comment.asFeas yrSrrrrrrrr __classcell__rs@rQr r sW&& rSr c(eZdZdZddZdZddZdS) NullGlyphz5The NULL glyph, used in glyph deletion substitutions.Nc<t||dSr)r'rrs rQrzNullGlyph.__init__sD(+++++rScdS)BThe glyphs in this class as a tuple of :class:`GlyphName` objects.rNrNrs rQglyphSetzNullGlyph.glyphSetsrrSrcdS)NNULLrNrs rQrzNullGlyph.asFeasvrSrrrrrrrrrrNrSrQrrsQ??,,,,rSrc(eZdZdZddZdZddZdS) r z)A single glyph name, such as ``cedilla``.NcJt||||_dSr)r'rglyph)rrrs rQrzGlyphName.__init__s#D(+++ rSc|jfSr)rrs rQrzGlyphName.glyphSets  }rSrc*t|jSr)rrrs rQrzGlyphName.asFeasTZ   rSrrrrNrSrQr r sQ33 !!!!!!rSr cFeZdZdZd dZdZd dZdZdZd Z d Z d Z dS)r z1A glyph class, such as ``[acute cedilla grave]``.Ncnt||||ng|_g|_d|_dS)Nr)r'rglyphsoriginalcurr)rrrs rQrzGlyphClass.__init__s:D(+++ & 2ff   rSc*t|jSr)rrrs rQrzGlyphClass.glyphSetsT[!!!rSrct|jr|jt|jkrE|j|j|jdt|j|_ddt t|jzdzSddt t|jzdzS)N[ ])rrrrextendrTmaprrs rQrzGlyphClass.asFeas t}   Ay3t{++++ $$T[%=>>> ,, #eT]";";<<s~&&(((rSrc d|jjzSr)rrrs rQrzMarkClassName.asFeaBsT^(((rSrrrrNrSrQrr5sWCC#### )))))))))rSrc"eZdZdZddZddZdS)rzAn anonymous data block.NcXt||||_||_dSr)rBrtagcontent)rrrrs rQrzAnonymousBlock.__init__Is*4*** rSrcd|j}||jz }|d|jz }|S)Nz anon {} {{ z}} {}; )rrrrrress rQrzAnonymousBlock.asFeaNsB##DH-- t| |""48,,, rSrrrrrrrrrNrSrQrrFsB"" rSrc(eZdZdZddZdZddZdS) rz,A block of statements: feature, lookup, etc.NcJt||g|_dSr)rBr statementsrs rQrzBlock.__init__Xs#4***rScD|jD]}||dS)zWhen handed a 'builder' object of comparable interface to :class:`fontTools.feaLib.builder`, walks the statements in this block, calling the builder callbacks.N)rr)rrss rQrz Block.build\s4  A GGG      rSrcvtz dzfd|jDzdzS)N c<g|]}|SrrrOrrs rQ zBlock.asFea..gs'#T#T#TqAGG6G$:$:#T#T#TrS)SHIFTrTrrs `rQrz Block.asFeacsN% f}""#T#T#T#TDO#T#T#TUU V  rSrrrrrrrrrrNrSrQrrUsQ66      rSrc eZdZdZdZddZdS)r zpThe top-level element of the syntax tree, containing the whole feature file in its ``statements`` attribute.cLt|di|_dSN)r)rr markClassesrs rQrzFeatureFile.__init__ps& td+++rSrcPdfd|jDS)Nrc3DK|]}|VdS)rNrrs rQrRz$FeatureFile.asFea..us1IIA//IIIIIIrS)rTrrs `rQrzFeatureFile.asFeats,yyIIIIIIIIIIrSNrrrNrSrQr r lsG--JJJJJJrSr c(eZdZdZddZdZd dZdS) rzA named feature block.FNcZt||||c|_|_dSrrrr use_extensionrrrrs rQrzFeatureBlock.__init__{- tX&&&(,m% 4%%%rScj||j|j|j|j}i|_t |||jD].\}}||g |/||_| dS)Call the ``start_feature`` callback on the builder object, visit all the statements in this feature, and then call ``end_feature``.N) start_featurerrr features_rritems setdefaultr end_feature)rrfeatureskeyvalues rQrzFeatureBlock.builds dmTY8JKKK$ D'"""!+1133 7 7JC   R ( ( / / 6 6 6 6$rSrc|d|jzz}|jr|dz }|dz }|t||z }||d|jzzz }|S)Nz feature %s useExtension { r} %s; )rstriprrrrs rQrzFeatureBlock.asFeasz}ty'8'888   # ? "C u  u{{4{/// v DIOO$5$5555 rSFNrrrNrSrQrrxsQ  <<<<   rSrc(eZdZdZddZdZddZdS) rzYA block inside another block, for example when found inside a ``cvParameters`` block.NcXt||||_||_dSr)rrr block_name)rrr&rs rQrzNestedBlock.__init__s( tX&&&$rSct|||jdkr||jdSdS)NParamUILabelNameID)rrr&add_to_cv_num_named_paramsrrs rQrzNestedBlock.buildsH D'""" ?2 2 2  . .tx 8 8 8 8 8 3 2rSrcd||j}|t||z }|d|z }|S)Nz{}{} {{ rz{}}}; )rr&rrrs rQrzNestedBlock.asFeasP  99 u{{4{/// y''' rSrrrrNrSrQrrsU%%%% 999 rSrc(eZdZdZddZdZd dZdS) rz*A named lookup, containing ``statements``.FNcZt||||c|_|_dSrrrs rQrzLookupBlock.__init__rrSc||j|j|jt|||dSr)start_lookup_blockrrrrrend_lookup_blockrs rQrzLookupBlock.buildsM""4=$)T=OPPP D'"""  """""rSrcd|j}|jr|dz }|dz }|t||z }|d||jz }|S)Nz lookup {} rr rz {}}} {}; )rrrrrrs rQrzLookupBlock.asFeasp!!$),,   # ? "C u  u{{4{/// |""649555 rSr#rrrNrSrQrrsQ44<<<<### rSrc,eZdZdZddZdfd ZxZS)rGzA ``table ... { }`` block.NcJt||||_dSr)rrr)rrrs rQrzTableBlock.__init__s! tX&&& rSrcd|j}|tt||z }|d|jz }|S)Nz table {} {{ rz}} {}; )rrr"rrGr)rrrrs rQrzTableBlock.asFeasp$$TY__%6%677 uZ&&,,F,;;; z  !2!2333 rSrrrrs@rQrGrGsW$$rSrGc(eZdZdZddZdZddZdS) rz!Example: ``@UPPERCASE = [A-Z];``.NcXt||||_||_dSr)rBrrr)rrrrs rQrzGlyphClassDefinition.__init__s*4***  rScNt|jSr)rrrrs rQrzGlyphClassDefinition.glyphSetsT[))++,,,rSrcVd|jzdz|jzdzS)Nrz = ;)rrrrs rQrzGlyphClassDefinition.asFeas+TY&):):)<)<rs rQrzGlyphClassDefStatement.__init__s@ 4***,6 (,.rSc|jr|jn t}|jr|jn t}|jr|jn t}|jr|jn t}||j||||dS)z3Calls the builder's ``add_glyphClassDef`` callback.N)r;rrr=r<r>add_glyphClassDefr)rrrligarocomps rQrzGlyphClassDefStatement.builds-1_It'')))%''151DQt"++---%''-1_It'')))%''262FSt#,,...EGG!!$-tT4HHHHHrSrc2d|jr|jnd|jr|jnd|jr|jnd|jr|jndS)NzGlyphClassDef {}, {}, {}, {};r)rr;rr=r<r>rs rQrzGlyphClassDefStatement.asFeas.55'+ >DO ! ! # # #B+/+> FD  % % ' ' 'B'+ >DO ! ! # # #B,0,@ HD & & ( ( (b    rSrrrrNrSrQrrs_ QU////III      rSrc,eZdZdZdZdZdZddZdS) raBOne `or more` ``markClass`` statements for the same mark class. While glyph classes can be defined only once, the feature file format allows expanding mark classes with multiple definitions, each using different glyphs and anchors. The following are two ``MarkClassDefinitions`` for the same ``MarkClass``:: markClass [acute grave] @FRENCH_ACCENTS; markClass [cedilla] @FRENCH_ACCENTS; The ``MarkClass`` object is therefore just a container for a list of :class:`MarkClassDefinition` statements. cH||_g|_t|_dSr)r definitionsrr)rrs rQrzMarkClass.__init__ s  !mm rScNt|tsJ|jt j||D]L}||jvr7|j|j}|d}nd|}td|d||j||j|<MdS)z@Add a :class:`MarkClassDefinition` statement to this mark class.Nrz at zGlyph z already defined) rrrFrweakrefproxyrrrr)r definitionrotherLocrs rQ addDefinitionzMarkClass.addDefinitions*&9:::::  j 9 9:::((** , ,E ##;u-6#CC+++C%o49EE33?AT",DK   , ,rScNt|jSr)rrkeysrs rQrzMarkClass.glyphSet"sT[%%''(((rSrcNdd|jD}|S)Nrc3>K|]}|VdSrr)rOds rQrRz"MarkClass.asFea..'s*< @FRENCH_ACCENTS; # markClass [cedilla] @FRENCH_ACCENTS; Nct||t|tsJt|trt|t sJ|||c|_|_|_dSr) rBrrrrr'rrWr)rrrWrrs rQrzMarkClassDefinition.__init__Bsm4***)Y/////&&))Lj.L.LLLL3.b 4441!**,,444rSc6g|]}|SrNr]rOrs rQrz1AlternateSubstStatement.build..cr`rSN) rrrlistrXrYrZadd_alternate_substr)rrrrXrYrZs rQrzAlternateSubstStatement.build]s ##%%5zzQU A44 44444 444&//11 ##DM65&+VVVVVrSrcd}t|jst|jrt|jr3|dt t |jdzz }|t |jdzz }t|jr3|ddt t |jzz }n|t |jz }|dz }|t |jz }|dz }|S)Nsub r'z from r8)rrXrYrTrrrrZrs rQrzAlternateSubstStatement.asFeags t{   %s4;// %4; ?sxxE4; 7 7883>> 5$$s* *C4; ?sSXXc%&=&=>>>> 5$$ $C x uT%&&& s  rSrrrrNrSrQrrRsZQQ '''' WWW      rSrc,eZdZdZ ddZddZdS)rzAn ``Anchor`` element, used inside a ``pos`` rule. If a ``name`` is given, this will be used in preference to the coordinates. Other values should be integer. Nct||||_|||c|_|_|_||c|_|_dSr)r'rrxy contourpoint xDeviceTable yDeviceTable)rrjrkrrlrmrnrs rQrzAnchor.__init__~sP D(+++ ,-q,))/;\,4,,,rSrcf|jd|jSd|j|j}|jr|d|jz }|js|jr8|dz }|t|jz }|dz }|t|jz }|dz }|S)Nz z )rrrjrkrlrmrnrVrs rQrz Anchor.asFeas 9  '' 22 2$$TVTV44   @ %,,T->?? ?C   5 1 5 3JC >$"344 4C 3JC >$"344 4C s  rS)NNNNNrrrNrSrQrrws[ J J J J      rSrc"eZdZdZddZddZdS)rzCA named anchor definition. (2.e.viii). ``name`` should be a string.Nczt||||||f\|_|_|_|_dSr)rBrrrjrkrl)rrrjrkrlrs rQrzAnchorDefinition.__init__s>4***7;Q<7O4 46464#4#4#4rSrcd|j|j}|jr|d|jz }|d|jz }|S)NzanchorDef {} {}rpz {};)rrjrkrlrrs rQrzAnchorDefinition.asFeas`&&tvtv66   @ %,,T->?? ?C v}}TY''' rSrrrrNrSrQrrsFMMPPPPrSrc(eZdZdZddZdZddZdS) rz&A ``GDEF`` table ``Attach`` statement.NcXt||||_||_dSr)rBrr contourPoints)rrrwrs rQrzAttachStatement.__init__s-4*** *rScz|j}||j||jdS)z3Calls the builder's ``add_attach_points`` callback.N)rradd_attach_pointsrrwrrrs rQrzAttachStatement.builds8%%''!!$-9KLLLLLrSrcd|jdd|jDS)Nz Attach {} {};rc34K|]}t|VdSrstr)rOcs rQrRz(AttachStatement.asFea..s()M)MQ#a&&)M)M)M)M)M)MrS)rrrrTrwrs rQrzAttachStatement.asFeasK%% K    )M)M$:L)M)M)M!M!M   rSrrrrNrSrQrrsT00++++ MMM       rSrc(eZdZdZddZdZddZdS) r a@A chained contextual positioning statement. ``prefix``, ``glyphs``, and ``suffix`` should be lists of `glyph-containing objects`_ . ``lookups`` should be a list of elements representing what lookups to apply at each glyph position. Each element should be a :class:`LookupBlock` to apply a single chaining lookup at the given position, a list of :class:`LookupBlock`\ s to apply multiple lookups, or ``None`` to apply no lookup. The length of the outer list should equal the length of ``glyphs``; the inner lists can be of variable length.Nct|||||c|_|_|_t ||_t|D]3\}}|r, t|#t$r|g|j|<Y/wxYw4dSr rBrrXrrYrclookupsr_iter TypeErrorrrXrrYrrirms rQrz!ChainContextPosStatement.__init__4***06- T[$+G}} "7++ / /IAv //LLLL ///'-hDLOOO/ / / /A--BBcd|jD}d|jD}d|jD}||j||||jdS)z7Calls the builder's ``add_chain_context_pos`` callback.c6g|]}|SrNr]r^s rQrz2ChainContextPosStatement.build..r`rSc6g|]}|SrNr]rOrs rQrz2ChainContextPosStatement.build..r`rSc6g|]}|SrNr]rbs rQrz2ChainContextPosStatement.build..r`rSN)rXrrYadd_chain_context_posrrrrrXrrYs rQrzChainContextPosStatement.buildsr44 44444 44444 444%% M6664<     rSrc d}t|js3t|jstd|jDrt|jr*|dd|jDdzz }t |jD]i\}}||dzz }|j|r|j|D]}|d|j zz }|t|jdz kr|dz }jt|jr3|ddtt|jzz }n0|dtt|jz }|dz }|S) Npos cg|]}|duSrrNrOrjs rQrz2ChainContextPosStatement.asFea..888aATM888rSrc3>K|]}|VdSrrrs rQrRz1ChainContextPosStatement.asFea..*??a ??????rSrg lookup rr8 rrXrYanyrrTr_rrrrrrrrrlus rQrzChainContextPosStatement.asFea    54; 5884<88899 5 4; Fsxx??4;?????#EE!$+..  1qwwyy3&<?4"l1o44zBG33s4;''!+++3JC4; ?sSXXc%&=&=>>>> 388Ct{3344 4C s  rSrrrrNrSrQr r U   / / / /   rSr c(eZdZdZddZdZddZdS) r!aAA chained contextual substitution statement. ``prefix``, ``glyphs``, and ``suffix`` should be lists of `glyph-containing objects`_ . ``lookups`` should be a list of elements representing what lookups to apply at each glyph position. Each element should be a :class:`LookupBlock` to apply a single chaining lookup at the given position, a list of :class:`LookupBlock`\ s to apply multiple lookups, or ``None`` to apply no lookup. The length of the outer list should equal the length of ``glyphs``; the inner lists can be of variable length.Nct|||||c|_|_|_t ||_t|D]3\}}|r, t|#t$r|g|j|<Y/wxYw4dSrrrs rQrz#ChainContextSubstStatement.__init__rrcd|jD}d|jD}d|jD}||j||||jdS)z9Calls the builder's ``add_chain_context_subst`` callback.c6g|]}|SrNr]r^s rQrz4ChainContextSubstStatement.build..r`rSc6g|]}|SrNr]rs rQrz4ChainContextSubstStatement.build..r`rSc6g|]}|SrNr]rbs rQrz4ChainContextSubstStatement.build..r`rSN)rXrrYadd_chain_context_substrrrs rQrz ChainContextSubstStatement.buildsr44 44444 44444 444'' M6664<     rSrc d}t|js3t|jstd|jDrt|jr*|dd|jDdzz }t |jD]i\}}||dzz }|j|r|j|D]}|d|j zz }|t|jdz kr|dz }jt|jr3|ddtt|jzz }n0|dtt|jz }|dz }|S) Nrfcg|]}|duSrrNrs rQrz4ChainContextSubstStatement.asFea..rrSrc3>K|]}|VdSrrrs rQrRz3ChainContextSubstStatement.asFea.."rrSrgrrr8rrs rQrz ChainContextSubstStatement.asFearrSrrrrNrSrQr!r!rrSr!c(eZdZdZddZdZddZdS) r$znA cursive positioning statement. Entry and exit anchors can either be :class:`Anchor` objects or ``None``.Ncht||||_||c|_|_dSr)rBrr entryAnchor exitAnchor)rrrrrs rQrzCursivePosStatement.__init__6s44***$,7)$///rSc||j|j|j|jdS)z8Calls the builder object's ``add_cursive_pos`` callback.N)add_cursive_posrrrrrrs rQrzCursivePosStatement.build;sB M4?3355t7G     rSrc|jr|jnd}|jr|jnd}d|j||S)N zpos cursive {} {} {};)rrrrr)rrentryexits rQrzCursivePosStatement.asFeaAsh,0,<Q &&(((/*./Nt$$&&&&--do.C.C.E.EudSSSrSrrrrNrSrQr$r$2s_//DDDD    TTTTTTrSr$c(eZdZdZddZdZddZdS) r)zExample: ``feature salt;``NcZt||||c|_|_dSr)rBrr featureName)rrrs rQrz"FeatureReferenceStatement.__init__Js/4***+3[' t'''rScF||j|jdS)z>Calls the builder object's ``add_feature_reference`` callback.N)add_feature_referencerrrs rQrzFeatureReferenceStatement.buildNs#%%dmT5EFFFFFrSrc6d|jS)Nz feature {};)rrrs rQrzFeatureReferenceStatement.asFeaRs##D$4555rSrrrrNrSrQr)r)GsX$$BBBBGGG666666rSr)c(eZdZdZddZdZddZdS) r,zAn ``ignore pos`` statement, containing `one or more` contexts to ignore. ``chainContexts`` should be a list of ``(prefix, glyphs, suffix)`` tuples, with each of ``prefix``, ``glyphs`` and ``suffix`` being `glyph-containing objects`_ .NcJt||||_dSrrBr chainContextsrrrs rQrzIgnorePosStatement.__init__]&4****rSc|jD]H\}}}d|D}d|D}d|D}||j|||gIdS)z[Calls the builder object's ``add_chain_context_pos`` callback on each rule context.c6g|]}|SrNr]r^s rQrz,IgnorePosStatement.build..e 333qajjll333rSc6g|]}|SrNr]rs rQrz,IgnorePosStatement.build..frrSc6g|]}|SrNr]rbs rQrz,IgnorePosStatement.build..grrSN)rrrrs rQrzIgnorePosStatement.buildas'+&8 U U "FFF33F333F33F333F33F333F  ) )$-QS T T T T  U UrSrc Vg}|jD]\}}}d}t|st|rt|r.|dtt|dzz }|dd|Dz }t|r.|ddtt|zz }n+|dtt|z }||dd|zdzS)Nrrc3DK|]}|dzVdSrgNrrs rQrRz+IgnorePosStatement.asFea..qs.@@A C@@@@@@rSz ignore pos rLr8rrrTrrrrrcontextsrXrrYrs rQrzIgnorePosStatement.asFeajs&*&8 ! ! "FFFC6{{ 4c&kk 4v;;>388Cv$6$677#==Csxx@@@@@@@@v;;>3#eV*<*.rrSc6g|]}|SrNr]rs rQrz.IgnoreSubstStatement.build..rrSc6g|]}|SrNr]rbs rQrz.IgnoreSubstStatement.build..rrSN)rrrrs rQrzIgnoreSubstStatement.builds'+&8 W W "FFF33F333F33F333F33F333F  + +DM666SU V V V V  W WrSrc g}|jD]\}}}d}t|r.|dtt|dzz }|dd|Dz }t|r.|ddtt|zz }||dd|zdzS)Nrrc3DK|]}|dzVdSrrrs rQrRz-IgnoreSubstStatement.asFea..s.<<AGGIIO<<<<<]] 0]      rSrcd|j}|js|dz }|jr|dz }|dz }|S)Nz language {}z exclude_dfltz requiredr8)rrkr"rrwrs rQrzLanguageStatement.asFeasZ""4=#6#6#8#899# # ? "C =  ; C s  rS)TFNrrrNrSrQr/r/sQ44!!!!   rSr/c(eZdZdZddZdZddZdS) r0z)A top-level ``languagesystem`` statement.NcZt||||c|_|_dSr)rBrr{rk)rr{rkrs rQrz LanguageSystemStatement.__init__s,4***&,h" T]]]rScR||j|j|jdS)z.()F)FQ#a&&)F)F)F)F)F)FrSrrrrTrrs rQrz#LigatureCaretByIndexStatement.asFeasJ,33 K    )F)F$+)F)F)F!F!F   rSrrrrNrSrQr1r1sZRR4444SSS       rSr1c(eZdZdZddZdZddZdS) r2zA ``GDEF`` table ``LigatureCaretByPos`` statement. ``glyphs`` should be a `glyph-containing object`_, and ``carets`` should be a list of integers.NcZt||||c|_|_dSrrrs rQrz$LigatureCaretByPosStatement.__init__rrSc|j}||j|t |jdS)z@Calls the builder object's ``add_ligatureCaretByPos_`` callback.N)rradd_ligatureCaretByPos_rrrrzs rQrz!LigatureCaretByPosStatement.builds?%%'''' vs4;?O?OPPPPPrSrcd|jdd|jDS)NzLigatureCaretByPos {} {};rc34K|]}t|VdSrr}rs rQrRz4LigatureCaretByPosStatement.asFea.. rrSrrs rQrz!LigatureCaretByPosStatement.asFea sJ*11 K    )F)F$+)F)F)F!F!F   rSrrrrNrSrQr2r2sZRR4444QQQ       rSr2c(eZdZdZddZdZddZdS) r3aSA chained contextual substitution statement. ``prefix``, ``glyphs``, and ``suffix`` should be lists of `glyph-containing objects`_; ``replacement`` should be a single `glyph-containing object`_. If ``forceChain`` is True, this is expressed as a chaining rule (e.g. ``sub f' i' by f_i``) even when no context is given.Nct|||||c|_|_|_||c|_|_dSr)rBrrXrrYrZ forceChain)rrXrrYrZrrs rQrzLigatureSubstStatement.__init__sC4***17- T[$+,7)$///rScd|jD}d|jD}d|jD}||j||||j|jdS)Nc6g|]}|SrNr]r^s rQrz0LigatureSubstStatement.build..r`rSc6g|]}|SrNr]rs rQrz0LigatureSubstStatement.build.. r`rSc6g|]}|SrNr]rbs rQrz0LigatureSubstStatement.build..!r`rS)rXrrYadd_ligature_substrrZrrs rQrzLigatureSubstStatement.buildsw44 44444 44444 444"" M66643CT_     rSrc@d}t|jst|js|jrt|jr*|dd|jDdzz }|dd|jDz }t|jr*|ddd|jDzz }n'|dd|jDz }|dz }|t |jz }|dz }|S) Nrfrc3>K|]}|VdSrrrs rQrRz/LigatureSubstStatement.asFea..*rrSc3DK|]}|dzVdSrrrs rQrRz/LigatureSubstStatement.asFea..+s.AAAGGIIOAAAAAArSc3>K|]}|VdSrrrs rQrRz/LigatureSubstStatement.asFea..-s*%E%EAaggii%E%E%E%E%E%ErSc3>K|]}|VdSrrrs rQrRz/LigatureSubstStatement.asFea../s*;;!AGGII;;;;;;rS by r8)rrXrYrrTrrrZrs rQrzLigatureSubstStatement.asFea&s, t{   mark @TOP_MARKS # ligComponent mark @BOTTOM_MARKS; NcZt||||c|_|_dSr)rBr ligaturesr!)rr+r!rs rQrzMarkLigPosStatement.__init__,4***%." rScv||j|j|jdS)z9Calls the builder object's ``add_mark_lig_pos`` callback.N)add_mark_lig_posrr+rr!rs rQrzMarkLigPosStatement.builds2  0G0G0I0I4:VVVVVrSrcd|j}g}|jD]}d}|t |sd|zt dzzdz}nI|D]F\}}|d|zt dzzd||jzz }G|||d|zt zdz|z }|dz }|S) Nzpos ligature {}rrrrr% ligComponentr8) rr+rr!rrrrrT)rrrligsltempr'r(s rQrzMarkLigPosStatement.asFeas &&t~';';'='=>>  ADyAyf}uqy0?BDAq !!)$(..qwwyy!&AABDD KK     v %6<#7#7#9#9::J S SDAq 4&=5(=+?+? 16+R+RR RCC s  rSrrrrNrSrQr8r8sX556666XXXrSr8c*eZdZdZ ddZdZd dZdS) r9aA multiple substitution statement. Args: prefix: a list of `glyph-containing objects`_. glyph: a single glyph-containing object. suffix: a list of glyph-containing objects. replacement: a list of glyph-containing objects. forceChain: If true, the statement is expressed as a chaining rule (e.g. ``sub f' i' by f_i``) even when no context is given. FNct|||||c|_|_|_||_||_dSr)rBrrXrrYrZr)rrXrrYrZrrs rQrzMultipleSubstStatement.__init__sC 4***/5uf, TZ&$rSc d|jD}d|jD}t|jdr|j}n|jg}t |}g}|jD]j}t|dr|}n|g}t |dkrt ||kr||z}||ktt|}t} t|D]L\} } | | vrC| | | |j|| ||r|| pd|jMdS)z;Calls the builder object's ``add_multiple_subst`` callback.c6g|]}|SrNr]r^s rQrz0MultipleSubstStatement.build..r`rSc6g|]}|SrNr]rbs rQrz0MultipleSubstStatement.build..r`rSrrrNN)rXrYrrrrrZrrcziprr_addadd_multiple_substrr) rrrXrY originalscountreplacesrreplaceseen_originalsrrs rQrzMultipleSubstStatement.builds44 44444 444 4:z * * % ++--II II! % %Aq*%% **,,#7||q  S\\U%:%:!E/ OOG $ $ $ $X''$Y//  KAx~--""8,,,**M,!2O   rSrc~d}t|jst|js|jrt|jr3|dt t |jdzz }|t |jdzz }t|jr3|ddt t |jzz }n|t |jz }|jptg}|dz }|dt t |z }|dz }|S)Nrfrrgr r8) rrXrYrrTrrrrZr)rrrrZs rQrzMultipleSubstStatement.asFeas t{   %s4;// %4? %4; ?sxxE4; 7 7883>> 5$$s* *C4; ?sSXXc%&=&=>>>> 5$$ $C&79;;-  v  sxxE;//000 s  rSr#rrrNrSrQr9r9s]  NR%%%%BrSr9c,eZdZdZ ddZdZd dZdS) r<aA pair positioning statement. ``glyphs1`` and ``glyphs2`` should be `glyph-containing objects`_. ``valuerecord1`` should be a :class:`ValueRecord` object; ``valuerecord2`` should be either a :class:`ValueRecord` object or ``None``. If ``enumerated`` is true, then this is expressed as an `enumerated pair `_. FNct||||_||c|_|_||c|_|_dSr)rBr enumeratedglyphs1 valuerecord1glyphs2 valuerecord2)rrLrMrNrOrKrs rQrzPairPosStatement.__init__"sI 4***$*1<' d'*1<' d'''rSc|jr|j|jg}d}t j|D]/\}}d}||j||j||j 0|std|jdSt|jtot|jt}|r>||j|jj |j|jj |j dS||j|j|j|j|j dS)aMCalls a callback on the builder object: * If the rule is enumerated, calls ``add_specific_pair_pos`` on each combination of first and second glyphs. * If the glyphs are both single :class:`GlyphName` objects, calls ``add_specific_pair_pos``. * Else, calls ``add_class_pair_pos``. FTz%Empty glyph class in positioning ruleN)rKrLrrN itertoolsproductadd_specific_pair_posrrMrOrrr radd_class_pair_pos)rrr seen_pairglyph1glyph2 is_specifics rQrzPairPosStatement.build0s ? &&(($,*?*?*A*ABAI"+"3Q"7   --M64+.{ 8881!**,,888rSc6g|]}|SrNr]rbs rQrz:ReverseChainSingleSubstStatement.build..|rarSrr) r\r]rrr^radd_reverse_chain_single_substrdictr?rrrXrYrBrDs rQrz&ReverseChainSingleSubstStatement.buildzs8888888888KN++-- $Q'0022 x==A  #i..0H.. M664Ix0H0H+I+I     rSrcvd}t|jst|jrt|jr*|dd|jDdzz }|dd|jDz }t|jr*|ddd|jDzz }n0|dt t |jz }|ddd|jDz }|S)Nzrsub rc34K|]}t|VdSrrrs rQrRz9ReverseChainSingleSubstStatement.asFea..s(BBQaBBBBBBrSc3:K|]}t|dzVdSrrrs rQrRz9ReverseChainSingleSubstStatement.asFea..,@@qE!HHsN@@@@@@rSc34K|]}t|VdSrrrs rQrRz9ReverseChainSingleSubstStatement.asFea..s(%H%H1eAhh%H%H%H%H%H%HrS by {};c34K|]}t|VdSrrrs rQrRz9ReverseChainSingleSubstStatement.asFea..((M(Maq(M(M(M(M(M(MrS) rr\r]rTrrrrr^rs rQrz&ReverseChainSingleSubstStatement.asFeas- t   53t#7#7 54?## IsxxBB$/BBBBBSHH 388@@DK@@@@@ @C4?## IsSXX%H%H%H%H%HHHHH 388Ct{3344 4C y(M(M4;L(M(M(M M MNNN rSrrrrNrSrQr=r=ksU))))          rSr=c(eZdZdZddZdZddZdS) r@a.A single substitution statement. Note the unusual argument order: ``prefix`` and suffix come `after` the replacement ``glyphs``. ``prefix``, ``suffix``, ``glyphs`` and ``replace`` should be lists of `glyph-containing objects`_. ``glyphs`` and ``replace`` should be one-item lists. Nct||||c|_|_||_||_||_dSr)rBrrXrYrrr^)rrrFrXrYrrs rQrzSingleSubstStatement.__init__sD4***#)6  T[$ #rSc d|jD}d|jD}|jd}|jd}t |dkr|t |z}||j||tt|||j dS)z9Calls the builder object's ``add_single_subst`` callback.c6g|]}|SrNr]r^s rQrz.SingleSubstStatement.build..r`rSc6g|]}|SrNr]rbs rQrz.SingleSubstStatement.build..r`rSrrN) rXrYrrr^radd_single_substrrr?rres rQrzSingleSubstStatement.builds44 44444 444KN++-- $Q'0022 x==A  #i..0H  M   Ix00 1 1 O      rSrcrd}t|jst|js|jrt|jr*|dd|jDdzz }|dd|jDz }t|jr*|ddd|jDzz }n'|dd|jDz }|ddd|jDz }|S) Nrfrc34K|]}t|VdSrrrs rQrRz-SingleSubstStatement.asFea..s(>>Qa>>>>>>rSc3:K|]}t|dzVdSrrrs rQrRz-SingleSubstStatement.asFea..rirSc34K|]}t|VdSrrrs rQrRz-SingleSubstStatement.asFea..s(%D%D1eAhh%D%D%D%D%D%DrSc34K|]}t|VdSrrrs rQrRz-SingleSubstStatement.asFea..s(::E!HH::::::rSrkc34K|]}t|VdSrrrs rQrRz-SingleSubstStatement.asFea..rmrS)rrXrYrrTrrr^rs rQrzSingleSubstStatement.asFeas; t{   ;s4;// ;4? ;4; Esxx>>$+>>>>>DD 388@@DK@@@@@ @C4; EsSXX%D%D %D%D%DDDDD 388::dk::::: :C y(M(M4;L(M(M(M M MNNN rSrrrrNrSrQr@r@sU$$$$        rSr@c(eZdZdZddZdZddZdS) r>zA ``script`` statement.NcJt||||_dSr)rBrr{)rr{rs rQrzScriptStatement.__init__s#4*** rScF||j|jdS)z,Calls the builder's ``set_script`` callback.N) set_scriptrr{rs rQrzScriptStatement.builds"4=$+66666rSrcZd|jS)Nz script {};)rr{r"rs rQrzScriptStatement.asFeas$""4;#4#4#6#6777rSrrrrNrSrQr>r>sQ!!777888888rSr>c(eZdZdZddZdZddZdS) r?zA single position statement. ``prefix`` and ``suffix`` should be lists of `glyph-containing objects`_. ``pos`` should be a one-element list containing a (`glyph-containing object`_, :class:`ValueRecord`) tuple.Ncvt|||||c|_|_|_||_dSr)rBrrurXrYr)rrurXrYrrs rQrzSinglePosStatement.__init__s94***-0&&*$+t{$rScd|jD}d|jD}d|jD}||j||||jdS)z7Calls the builder object's ``add_single_pos`` callback.c6g|]}|SrNr]r^s rQrz,SinglePosStatement.build..r`rSc6g|]}|SrNr]rbs rQrz,SinglePosStatement.build..r`rSc@g|]\}}||fSrNr])rOrrs rQrz,SinglePosStatement.build..s)>>>E e$>>>rSN)rXrYruadd_single_posrr)rrrXrYrus rQrzSinglePosStatement.buildsg44 44444 444>>TX>>>t}ffc4?SSSSSrSrc,d}t|jst|js|jrt|jr3|dt t |jdzz }|dd|jDz }t|jr3|ddt t |jzz }n'|dd|jDz }|dz }|S)Nrrcg|]B}t|ddz|dd|dzndzCS)rrgrNrrrrs rQrz,SinglePosStatement.asFea..sd!A$KK/0t/?adjjll**RIrScg|]?}t|ddz|d|dndz@S)rrrNrrrs rQrz,SinglePosStatement.asFea..sU!A$KK#%19I1rRrSr8)rrXrYrrTrrrurs rQrzSinglePosStatement.asFeas* t{   s4;// 4? 4; ?sxxE4; 7 7883>> 388"X  C4; ?sSXXc%&=&=>>>> 388!X C s  rSrrrrNrSrQr?r?sX$$ %%%% TTTrSr?c(eZdZdZddZdZddZdS) rFzRepresents a subtable break.Nc<t||dSr)rBrrs rQrzSubtableStatement.__init__s4*****rSc:||jdS)zr.hsF    D!  D (       rS)rrrrrrrr)rrs`rQ__bool__zValueRecord.__bool__gs=            rS) NNNNNNNNFNr) rrrrrrrrrr __nonzero__rNrSrQrHrH s$$!!!!(   &&&    * * * * X    KKKrSrHc"eZdZdZddZddZdS)rIz+Represents a named value record definition.NcXt||||_||_dSr)rBrrr)rrrrs rQrzValueRecordDefinition.__init__|s*4***  rSrcfd|j|jS)NzvalueRecordDef {} {};)rrrrrs rQrzValueRecordDefinition.asFeas(&--dj.>.>.@.@$)LLLrSrrrrNrSrQrIrIysH55 MMMMMMrSrIc|dkr|dkr|dkrdS|dkr|dkr|dkrdSd|||S)Nri rr1{} {} {}r)pideidlids rQsimplify_name_attributesrsV axxC1HHr cQhh3!88s  c3///rSc(eZdZdZddZdZddZdS) r:zRepresents a name record. (`Section 9.e. `_)Nct||||_||_||_||_||_dSr)rBrnameID platformID platEncIDlangIDstring)rrrrrrrs rQrzNameRecord.__init__s?4*** $"  rScv||j|j|j|j|j|jdS)z8Calls the builder object's ``add_name_record`` callback.N)add_name_recordrrrrrrrs rQrzNameRecord.buildsB M K O N K K      rSrc dt|j|j|j}|t d|jt |j||dkr?dfdtdtdD}n!dfd D}t|j|j|j}|dkr|d z }d |j ||S) NcJ|dkr|dkr|dvrt|S||zS)N ~)"\)chr)rescape_patterns rQescapez NameRecord.asFea..escapes3DyyQ$YY1L+@+@1vv %))rSzUnsupported encoding)encoding utf_16_berc g|]=}t|dzt|dzzd>S)rz\%04xr)rOrrrs rQrz$NameRecord.asFea..sYF71Q4==3.1q51B1BBHMMrSrrcBg|]}t|dS)z\%02xr)rObrs rQrz$NameRecord.asFea..s+%N%N%NqffWQZZ&B&B%N%N%NrSrznameid {} {}"{}";)rrrrrrrrrTrrrrr)rrrescaped_stringplatrrs @@rQrzNameRecord.asFeas! * * *t LL  !"8$-HH H DK( 3 3 3 { " "WW"1c!ffa00NN WW%N%N%N%NA%N%N%NOON'UU 2:: CKD"))$+t^LLLrSrrrrNrSrQr:r:s]KK    MMMMMMrSr:c eZdZdZdZddZdS)r(z4Represents a ``sizemenuname`` or ``name`` statement.cpt||||jdS)z8Calls the builder object's ``add_featureName`` callback.N)r:radd_featureNamerrs rQrzFeatureNameStatement.builds4w''' ,,,,,rSrc|jdkrd}nd}t|j|j|j}|dkr|dz }d|||jS)Nsize sizemenunamerrrz {} {}"{}";)rrrrrrr)rrrrs rQrzFeatureNameStatement.asFeas^ ;&  CCC'UU 2:: CKD""3dk:::rSNr)rrrrrrrNrSrQr(r(s=>>--- ;;;;;;rSr(ceZdZdZddZdS)rEz+Represents a STAT table ``name`` statement.rct|j|j|j}|dkr|dz }d||jSNrrz name {}"{}";rrrrrrrrrs rQrzSTATNameStatement.asFeaC'UU 2:: CKD$$T4;777rSNr)rrrrrrNrSrQrErEs.55888888rSrEc(eZdZdZddZdZddZdS) rAzA ``parameters`` statement.Nctt||||_||_||_||_dSr)rBr DesignSize SubfamilyID RangeStartRangeEnd)rrrrrrs rQrzSizeParameters.__init__s94***$&$  rScj||j|j|j|j|jdS)z## M O   O M      rSrcd|j|j}|jdks |jdkrC|dt |jdzt |jdzz }|dzS)Nzparameters {:.1f} {}rz {} {} r8)rrrrrintrs rQrzSizeParameters.asFeasv$++DOT=MNN ?a  4=A#5#5 8??3t';#<#U>UVV VCSyrSrrrrNrSrQrArAsQ%%!!!!   rSrAc*eZdZdZ ddZdZddZdS) rz;Represent a name statement inside a ``cvParameters`` block.Nc Vt|||||||||_dSr )r:rr&)rrrrrrr&rs rQrz"CVParametersNameStatement.__init__s=  &*i(    %rScd}|jdkr3d|j|jd}||j|j|j|zf|_t ||dS)z9Calls the builder object's ``add_cv_parameter`` callback.rr(z_{}rN)r&rcv_num_named_params_getradd_cv_parameterr:r)rritems rQrzCVParametersNameStatement.builds ?2 2 2<< < @ @a P PQQD  ---{DOd$:; w'''''rSrct|j|j|j}|dkr|dz }d||jSrrrs rQrzCVParametersNameStatement.asFea rrSrrrrNrSrQrrsXEESW%%%%(((888888rSrc(eZdZdZddZdZddZdS) r"a Statement used in cvParameters blocks of Character Variant features (cvXX). The Unicode value may be written with either decimal or hexadecimal notation. The value must be preceded by '0x' if it is a hexadecimal value. The largest Unicode value allowed is 0xFFFFFF. NcXt||||_||_dSr)rBr characterr)rrrrs rQrzCharacterStatement.__init__s*4***"rScF||j|jdS)z9Calls the builder object's ``add_cv_character`` callback.N)add_cv_characterrrrs rQrzCharacterStatement.builds"  :::::rSrc6d|jS)NzCharacter {:#x};)rrrs rQrzCharacterStatement.asFea#s!((888rSrrrrNrSrQr"r"sU ;;;999999rSr"c(eZdZdZddZdZddZdS) rzAn axis definition, being either a ``VertAxis.BaseTagList/BaseScriptList`` pair or a ``HorizAxis.BaseTagList/BaseScriptList`` pair.Nctt||||_||_||_g|_dSr)rBrbasesscriptsrminmax)rrrrrrs rQrzBaseAxis.__init__+s84***     rSc^||j|j|j|jdS)z6Calls the builder object's ``set_base_axis`` callback.N) set_base_axisrrrrrs rQrzBaseAxis.build2s*dj$, t{SSSSSrSrc |jrdndd|jD}fd|jD}dd|j|d|d|zS) NVertHorizc g|]Q}d|d|ddtt|dRS)rrrrr)rrTrr~)rOr's rQrz"BaseAxis.asFea..8sZ      adAaD#((3sAaD>>*B*B C C   rSc rg|]3}d|d|d|d|d4S)z {}Axis.MinMax {} {} {}, {};rrrrr)rOr' directions rQrz"BaseAxis.asFea..<sR    , 2 29adAaD!A$PQRSPT U U   rSz2{}Axis.BaseTagList {}; {}{}Axis.BaseScriptList {};rrLr)rrrrrTr)rrrminmaxesrs @rQrzBaseAxis.asFea6s"m8FF   \       [   EKK sxx ++VY '@R@R  IIh    rSrrrrNrSrQrr'sZ@@TTT       rSrc(eZdZdZddZdZddZdS) r;zAn entry in the ``OS/2`` table. Most ``values`` should be numbers or strings, apart from when the key is ``UnicodeRange``, ``CodePageRange`` or ``Panose``, in which case it should be an array of integers.NcXt||||_||_dSrrBrrrrrrrs rQrzOS2Field.__init__J*4*** rScF||j|jdS)z6Calls the builder object's ``add_os2_field`` callback.N) add_os2_fieldrrrs rQrzOS2Field.buildOs"dh 33333rSrcFdd}d}td|D}|fd|Ddg|d<dd g|d <|j|vrFd ||jd ||jd |jSdS)NcRdtt|S)Nr)rTrr~)rjs rQ intarr2strz"OS2Field.asFea..intarr2strTs88CQKK(( (rS) FSType TypoAscender TypoDescender TypoLineGap winAscent winDescentXHeight CapHeight WeightClass WidthClass LowerOpSize UpperOpSize) UnicodeRange CodePageRangecHg|]}||tgf SrN)rr~rs rQrz"OS2Field.asFea..fs)@@@1!''))aX.@@@rSc@g|]}||gfSrNr)rOrjr s rQrz"OS2Field.asFea..gs*FFF!!''))a_5FFFrSPanosepanoseVendorc,d|S)Nz"{}"r)rks rQz OS2Field.asFea..is&--2B2BrSvendor{} {};rrr)rdupdaterrr)rrnumbersrangeskeywordsr s @rQrzOS2Field.asFeaSs ) ) )  3@@@@@AAFFFFvFFFGGG& 3&(B(BC 8x  ??"1%'.$888A!''))Q888rSr%rdrrrrrfieldsr)s rQrzHheaField.asFea}s@D8888899x14:>>>rSrrrrNrSrQr+r+qQ)) 555??????rSr+c(eZdZdZddZdZddZdS) rJzAn entry in the ``vhea`` table.NcXt||||_||_dSrrrs rQrzVheaField.__init__rrScF||j|jdS)z7Calls the builder object's ``add_vhea_field`` callback.N)add_vhea_fieldrrrs rQrzVheaField.buildr.rSrcd}td|D}d||j|jS)N)VertTypoAscenderVertTypoDescenderVertTypoLineGapc:g|]}||fSrNrrs rQrz#VheaField.asFea..r5rSr%r6r7s rQrzVheaField.asFeas@M8888899x14:>>>rSrrrrNrSrQrJrJr9rSrJc(eZdZdZddZdZddZdS) rDzA STAT table Design Axis Args: tag (str): a 4 letter axis tag axisOrder (int): an int names (list): a list of :class:`STATNameStatement` objects Nctt||||_||_||_||_dSr)rBrr axisOrdernamesr)rrrErFrs rQrz STATDesignAxisStatement.__init__s84***"   rSc<|||jdSr) addDesignAxisrrs rQrzSTATDesignAxisStatement.builds dDM22222rSrctz d|jd|jd}|dzfd|jDdzz }|dz }|S)Nz DesignAxis rz { rc<g|]}|Srrrs rQrz1STATDesignAxisStatement.asFea..'$P$P$PQWWFW%;%;$P$P$PrS};)rrrErTrFrs ` rQrzSTATDesignAxisStatement.asFeaso%=DH==t~=== v ##$P$P$P$PTZ$P$P$PQQTXXX t  rSrrrrNrSrQrDrDsU!!!!333rSrDc(eZdZdZddZdZddZdS) r%ziSTAT table ElidedFallbackName Args: names: a list of :class:`STATNameStatement` objects NcXt||||_||_dSr)rBrrFr)rrFrs rQrzElidedFallbackName.__init__*4***   rScF||j|jdSr)setElidedFallbackNamerFrrs rQrzElidedFallbackName.build"%%dj$-@@@@@rSrctz d}|dzfd|jDdzz }|dz }|S)NzElidedFallbackName { rc<g|]}|Srrrs rQrz,ElidedFallbackName.asFea..rKrSrL)rrTrFrs ` rQrzElidedFallbackName.asFeasX%' v ##$P$P$P$PTZ$P$P$PQQTXXX t  rSrrrrNrSrQr%r%sX !!!! AAArSr%c(eZdZdZddZdZddZdS) r&zpSTAT table ElidedFallbackNameID Args: value: an int pointing to an existing name table name ID NcXt||||_||_dSr)rBrrr)rrrs rQrzElidedFallbackNameID.__init__rOrScF||j|jdSr)rQrrrs rQrzElidedFallbackNameID.buildrRrSrcd|jdS)NzElidedFallbackNameID r8)rrs rQrzElidedFallbackNameID.asFeas4tz4444rSrrrrNrSrQr&r&sX !!!! AAA555555rSr&c(eZdZdZddZdZddZdS) rCzA STAT table Axis Value Record Args: names (list): a list of :class:`STATNameStatement` objects locations (list): a list of :class:`AxisValueLocationStatement` objects flags (int): an int Ncft||||_||_||_dSr)rBrrF locationsr)rrFr[rrs rQrzSTATAxisValueStatement.__init__s14*** " rSc<|||jdSr)addAxisValueRecordrrs rQrzSTATAxisValueStatement.builds ""477777rSrcd}|jD]}||z }|jD]}||z }|dz }|jrqddg}g}d}t t |D]0}|j|zdkr||||dz}1|dd|d z }|d z }|S) Nz AxisValue { rOlderSiblingFontAttributeElidableAxisValueNamerrzflag r; rL)r[rrFrrrrrT) rrrr nameRecordr flagStringsrrs rQrzSTATAxisValueStatement.asFeas $ $H 8>>## #CC*  J :##%% %C 4KCC : 602IJEKD3u::&& ! !:$))&&uQx000qy 5388K00555 5C t  rSrrrrNrSrQrCrCsU 888rSrCc"eZdZdZddZddZdS)rz A STAT table Axis Value Location Args: tag (str): a 4 letter axis tag values (list): a list of ints and/or floats NcXt||||_||_dSr)rBrrvalues)rrrfrs rQrz#AxisValueLocationStatement.__init__ s*4*** rSrcv|d|jdz }|dd|jDdz }|S)Nz location rc34K|]}t|VdSrr})rOrs rQrRz3AxisValueLocationStatement.asFea..s(77a3q66777777rSra)rrTrf)rrs rQrz AxisValueLocationStatement.asFeasO &48&&&& #((774;77777<<<< rSrrrrNrSrQrrsF rSrc(eZdZdZddZdZddZdS) r#z A variable layout conditionset Args: name (str): the name of this conditionset conditions (dict): a dictionary mapping axis tags to a tuple of (min,max) userspace coordinates. NcXt||||_||_dSr)rBrr conditions)rrrkrs rQrzConditionsetStatement.__init__ s*4*** $rScR||j|j|jdSr)add_conditionsetrrrkrs rQrzConditionsetStatement.build%s&   4?KKKKKrSrc ||d|jdzdzz }|jD]!\}\}}||tz|d|d|dzz }"||dzd|jdzz }|S)Nz conditionset rr ra})rrkrr)rrrrminvaluemaxvalues rQrzConditionsetStatement.asFea(s v4 4444u<<)-)>)>)@)@ F F %C%(H 6E>s$E$EX$E$E$E$E$EE ECC v|0$)00000 rSr)rrrrNrSrQr#r#sX%%%% LLLrSr#c(eZdZdZddZdZd dZdS) VariationBlockzCA variation feature block, applicable in a given set of conditions.FNcht|||||c|_|_|_dSr)rrr conditionsetr)rrrurrs rQrzVariationBlock.__init__3s8 tX&&&    9 4$d&8&8&8rSc(||j|j|j|jdkr+|j|jvrt d|j|j|j}i|_t |||j D]W\}}|j |i |jg}| |||vrg||<X||_|dS)rrz,variation block used undefined conditionset N)rrrrruconditionsets_rrrrrfeature_variations_rrr)rrrrrrs rQrzVariationBlock.build;s( dmTY8JKKK   ' '!)???!Rt?PRR  $ D'"""!+1133 # #JC/::3CCNN!2E LL   ("" " $rSrc|d|jzz}||jdzz }|jr|dz }|dz }|t||z }||d|jzzz }|S)Nz variation %s rrr rr!)rr"rurrrrs rQrzVariationBlock.asFeaWs):)::: t 3&&   # ? "C u  u{{4{/// v DIOO$5$5555 rSr#rrrNrSrQrsrs0sQMM    8rSrs)YrHfontTools.feaLib.errorrfontTools.feaLib.locationrfontTools.misc.encodingToolsrfontTools.misc.textToolsrr collectionsrrQr__all__rVrrrobjectr rBr'r rr r rrrrr rrrrGrrrrrrrrr r!r$r)r,r-r.r/r0r*r1r2r3r4r5r6r7r8r9r<r=r@r>r?rFrHrIrr:r(rErArr"rr;r+rJrDr%r&rCrr#rsrNrSrQrsv 22222288888844444455555555######C C C LFFFs55577 tf,                     g            ! ! ! ! ! ! ! ! ;%;%;%;%;%;%;%;%|*****Z***")))))J)))"     Y        I   . J J J J J% J J J5>%*%,         C C C C C9 C C C      Y   <********Z$ $ $ $ $ )$ $ $ N"""""i"""J"""""Z"""J     y        i   &77777y777t77777777tTTTTT)TTT* 6 6 6 6 6 6 6 6!9!9!9!9!9!9!9!9H999999999B77777y777& : R R R R Ri R R R < < < <