L i!^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~eZMGddeZNGddeZOGddeZPGddeZQGddeZRGddeZSGddeZTGddeZUGddeZVGddeZWGddeZXy)N)FeatureLibError)FeatureLibLocation) getEncoding)byteordtobytes) OrderedDictz )BElement FeatureFileComment GlyphName GlyphClassGlyphClassName MarkClassNameAnonymousBlockBlock FeatureBlock NestedBlock LookupBlockGlyphClassDefinitionGlyphClassDefStatement MarkClassMarkClassDefinitionAlternateSubstStatementAnchorAnchorDefinitionAttachStatementAxisValueLocationStatementBaseAxisCVParametersNameStatementChainContextPosStatementChainContextSubstStatementCharacterStatementConditionsetStatementCursivePosStatementElidedFallbackNameElidedFallbackNameID ExpressionFeatureNameStatementFeatureReferenceStatementFontRevisionStatement HheaFieldIgnorePosStatementIgnoreSubstStatementIncludeStatementLanguageStatementLanguageSystemStatementLigatureCaretByIndexStatementLigatureCaretByPosStatementLigatureSubstStatementLookupFlagStatementLookupReferenceStatementMarkBasePosStatementMarkLigPosStatementMarkMarkPosStatementMultipleSubstStatement NameRecordOS2FieldPairPosStatement ReverseChainSingleSubstStatementScriptStatementSinglePosStatementSingleSubstStatementSizeParameters StatementSTATAxisValueStatementSTATDesignAxisStatementSTATNameStatementSubtableStatement TableBlock ValueRecordValueRecordDefinition VheaFieldc>|yddjd|DzS)Nz z , c3&K|] }d|z yw)z%d %dN).0ts Z/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/fontTools/feaLib/ast.py z!deviceToString..Us(E1(Es)join)devices rQdeviceToStringrUQs$ ~tyy(Ef(EEEE)4anchor anchordefanon anonymousbycontourcursiverTenum enumerate excludedflt exclude_dfltfeaturefromignoreignorebaseglyphsignoreligatures ignoremarksinclude includedflt include_dfltlanguagelanguagesystemlookup lookupflagmarkmarkattachmenttype markclassnameidnull parameterspospositionrequired righttoleft reversesubrsubscriptsub substitutesubtabletableusemarkfilteringset useextensionvaluerecorddefbasegdefheadhheanamevheavmtxct|dr|jSt|tr.t |dk(r t|ddzt|dzS|j t vrd|zS|S)NasFearz - \)hasattrr isinstancetuplelenlower fea_keywords)gs rQrrshq'wwy Au #a&A+QqT{U"U1Q4[00 l "axrVc,eZdZdZddZdZddZdZy) r z8A base class representing "something" in a feature file.NcF|rt|tst|}||_yN)rrlocationselfrs rQ__init__zElement.__init__s Jx1CD)84H  rVcyrrNrbuilders rQbuildz Element.builds rVct)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 "!rVc"|jSrrrs rQ__str__zElement.__str__szz|rVr)__name__ __module__ __qualname____doc__rrrrrNrVrQr r sB!  " rVr c eZdZy)rBNrrrrNrVrQrBrBrVrBc eZdZy)r'NrrNrVrQr'r'rrVr'c,eZdZdZdfd ZddZxZS)r zA comment in a feature file.c:tt| |||_yr)superr rtext)rrr __class__s rQrzComment.__init__s gt%h/ rVc|jSr)rrs rQrz Comment.asFeas yyrVrrrrrrrr __classcell__rs@rQr r s& rVr c&eZdZdZddZdZddZy) NullGlyphz5The NULL glyph, used in glyph deletion substitutions.Nc0tj||yr)r'rrs rQrzNullGlyph.__init__sD(+rVcy)BThe glyphs in this class as a tuple of :class:`GlyphName` objects.rNrNrs rQglyphSetzNullGlyph.glyphSetsrVcy)NNULLrNrs rQrzNullGlyph.asFeasrVrrrrrrrrrrNrVrQrrs?,rVrc&eZdZdZddZdZddZy)r z)A single glyph name, such as ``cedilla``.Nc>tj||||_yr)r'rglyph)rrrs rQrzGlyphName.__init__sD(+ rVc|jfSr)rrs rQrzGlyphName.glyphSets }rVc,t|jSr)rrrs rQrzGlyphName.asFeasTZZ  rVrrrrNrVrQr r s3 !rVr cDeZdZdZd dZdZd dZdZdZdZ d Z d Z y) r z1A glyph class, such as ``[acute cedilla grave]``.Ncbtj||||ng|_g|_d|_y)Nr)r'rglyphsoriginalcurr)rrrs rQrzGlyphClass.__init__s.D(+ & 2f   rVc,t|jSr)rrrs rQrzGlyphClass.glyphSetsT[[!!rVct|jr|jt|jkrL|jj |j|jdt|j|_ddj t t|jzdzSddj t t|jzdzS)N[ ])rrrrextendrSmaprrs rQrzGlyphClass.asFeas t}} yy3t{{++ $$T[[%=> , #eT]]";<s~~&&((rVc4d|jjzSr)rrrs rQrzMarkClassName.asFeaBsT^^((((rVrrrrNrVrQrr5sC# ))rVrc eZdZdZddZddZy)rzAn anonymous data block.NcLtj||||_||_yr)rBrtagcontent)rrrrs rQrzAnonymousBlock.__init__Is 4* rVcdj|j}||jz }|dj|jz }|S)Nz anon {} {{ z}} {}; )rrrrrress rQrzAnonymousBlock.asFeaNsB##DHH- t|| |""488,, rVrrrrrrrrrNrVrQrrFs" rVrc&eZdZdZddZdZddZy)rz,A block of statements: feature, lookup, etc.Nc>tj||g|_yr)rBr statementsrs rQrzBlock.__init__Xs4*rVcH|jD]}|j|y)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\s# A GGG  rVc |tz }|d|zj|jDcgc]}|j|c}zdzScc}w)N r)SHIFTrSrr)rrrs rQrz Block.asFeacsP% f}""DOO#TqAGG6G$:#TU V  #TsA rrrrrrrrrrNrVrQrrUs6 rVrceZdZdZdZddZy)r zpThe top-level element of the syntax tree, containing the whole feature file in its ``statements`` attribute.c@tj|di|_yN)r)rr markClassesrs rQrzFeatureFile.__init__ps td+rVcLdjfd|jDS)Nrc3BK|]}|jyw)rNr)rOrrs rQrRz$FeatureFile.asFea..usIA/Is)rSrrs `rQrzFeatureFile.asFeatsyyIIIIrVNrrrNrVrQr r ls-JrVr c&eZdZdZddZdZddZy)rzA named feature block.NcNtj||||c|_|_yrrrr use_extensionrrr rs rQrzFeatureBlock.__init__{! tX&(,m% 4%rVcl|j|j|j|j|j}i|_t j |||jjD]&\}}|j|gj|(||_|jy)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 dmmTYY8J8JK$$ D'"!++113 7JC   R ( / / 6 7$rVc|d|jjzz}|jr|dz }|dz }|tj ||z }||d|jjzzz }|S)Nz feature %s useExtension { r} %s; )rstripr rrrs rQrzFeatureBlock.asFeass}tyy'888    ? "C u  u{{4{// v DIIOO$5555 rVFNrrrNrVrQrrxs < rVrc&eZdZdZddZdZddZy)rzYA block inside another block, for example when found inside a ``cvParameters`` block.NcLtj||||_||_yr)rrr block_name)rrr"rs rQrzNestedBlock.__init__s tX&$rVctj|||jdk(r|j|jyy)NParamUILabelNameID)rrr"add_to_cv_num_named_paramsrrs rQrzNestedBlock.builds4 D'" ??2 2  . .txx 8 3rVcdj||j}|tj||z }|dj|z }|S)Nz{}{} {{ rz{}}}; )rr"rrrs rQrzNestedBlock.asFeasI  9 u{{4{// y'' rVrrrrNrVrQrrs% 9 rVrc&eZdZdZddZdZddZy)rz*A named lookup, containing ``statements``.NcNtj||||c|_|_yrr rs rQrzLookupBlock.__init__rrVc|j|j|j|jtj |||j yr)start_lookup_blockrrr rrend_lookup_blockrs rQrzLookupBlock.builds<""4==$))T=O=OP D'"  "rVcdj|j}|jr|dz }|dz }|tj ||z }|dj||jz }|S)Nz lookup {} rrrz {}}} {}; )rrr rrrs rQrzLookupBlock.asFeasi!!$)),    ? "C u  u{{4{// |""649955 rVrrrrNrVrQrrs4<# rVrc,eZdZdZddZdfd ZxZS)rGzA ``table ... { }`` block.c>tj||||_yr)rrr)rrrs rQrzTableBlock.__init__s tX& rVcdj|jj}|tt||z }|dj|jjz }|S)Nz table {} {{ rz}} {}; )rrrrrGr)rrrrs rQrzTableBlock.asFeas\$$TYY__%67 uZ,F,;; z  !233 rVrrrrs@rQrGrGs$rVrGc&eZdZdZddZdZddZy)rz!Example: ``@UPPERCASE = [A-Z];``.NcLtj||||_||_yr)rBrrr)rrrrs rQrzGlyphClassDefinition.__init__s 4*  rVcHt|jjSr)rrrrs rQrzGlyphClassDefinition.glyphSetsT[[))+,,rVcbd|jzdz|jjzdzS)Nrz = ;)rrrrs rQrzGlyphClassDefinition.asFeas,TYY&):):)<+>D   % % 'B'+DOO ! ! #B,0,@,@D & & (   GI   rVrrrrNrVrQrrs QU/I rVrc*eZdZdZdZdZdZddZy)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. c>||_g|_t|_yr)r definitionsrr)rrs rQrzMarkClass.__init__ s !m rVcft|tsJ|jjt j ||j D]^}||jvr?|j|j}|d}nd|}td|d||j||j|<`y)z@Add a :class:`MarkClassDefinition` statement to this mark class.Nrz at zGlyph z already defined) rrrBrweakrefproxyrrrr)r definitionrotherLocrs rQ addDefinitionzMarkClass.addDefinitions*&9:::  j 9:((* ,E #;;u-66#C  +C%493?ATAT",DKK  ,rVcHt|jjSr)rrkeysrs rQrzMarkClass.glyphSet"sT[[%%'((rVcJdjd|jD}|S)Nrc3<K|]}|jywrr)rOds rQrRz"MarkClass.asFea..'s @FRENCH_ACCENTS; # markClass [cedilla] @FRENCH_ACCENTS; Nctj||t|tsJt|trt|t sJ|||c|_|_|_yr) rBrrrrr'rrWr)rrrWrrs rQrzMarkClassDefinition.__init__BsQ4*)Y///&&)j.LLL3> 5$s* *C4;;sSXXc%&=>>> 5$ $C x uT%%&& s  rVrrrrNrVrQrrRsQ ' W rVrc*eZdZdZ ddZddZy)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. Nctj||||_|||c|_|_|_||c|_|_yr)r'rrxy contourpoint xDeviceTable yDeviceTable)rrarbrrcrdrers rQrzAnchor.__init__~sD D(+ ,-q,))/;\,4,rVc|jdj|jSdj|j|j}|jr|dj|jz }|j s |j r:|dz }|t|j z }|dz }|t|j z }|dz }|S)Nz z )rrrarbrcrdrerUrs rQrz Anchor.asFeas 99  '' 2 2$$TVVTVV4    %,,T->->? ?C    1 1 3JC >$"3"34 4C 3JC >$"3"34 4C s  rV)NNNNNrrrNrVrQrrws# J rVrc eZdZdZddZddZy)rzCA named anchor definition. (2.e.viii). ``name`` should be a string.Ncntj||||||f\|_|_|_|_yr)rBrrrarbrc)rrrarbrcrs rQrzAnchorDefinition.__init__s24*7;Q<7O4 46464#4rVcdj|j|j}|jr|dj|jz }|dj|jz }|S)NzanchorDef {} {}rgz {};)rrarbrcrrs rQrzAnchorDefinition.asFeas]&&tvvtvv6    %,,T->->? ?C v}}TYY'' rVrrrrNrVrQrrsMPrVrc&eZdZdZddZdZddZy)rz&A ``GDEF`` table ``Attach`` statement.NcLtj||||_||_yr)rBrr contourPoints)rrrnrs rQrzAttachStatement.__init__s!4* *rVc|jj}|j|j||jy)z3Calls the builder's ``add_attach_points`` callback.N)rradd_attach_pointsrrnrrrs rQrzAttachStatement.builds0%%'!!$--9K9KLrVcdj|jjdjd|jDS)Nz Attach {} {};rc32K|]}t|ywrstr)rOcs rQrRz(AttachStatement.asFea..s)MQ#a&)M)rrrrSrnrs rQrzAttachStatement.asFeas<%% KK   )M$:L:L)M!M  rVrrrrNrVrQrrs0+ M  rVrc&eZdZdZddZdZddZy)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.Nctj|||||c|_|_|_t ||_t|D]\}}|s t|y#t$r|g|j |<Y3wxYwr rBrrUrrVrYlookupsr_iter TypeErrorrrUrrVr{rirms rQrz!ChainContextPosStatement.__init__z4*06- T[$+G} "7+ /IAv/L /!/'-hDLLO/ A  A<;A<c^|jDcgc]}|j}}|jDcgc]}|j}}|jDcgc]}|j}}|j |j ||||j ycc}wcc}wcc}w)z7Calls the builder's ``add_chain_context_pos`` callback.N)rUrrrVadd_chain_context_posrr{rrr[rUrrrrVs rQrzChainContextPosStatement.builds(, 41!**,44(, 41!**,44(, 41!**,44%% MM6664<< 544B B%B*c,d}t|js;t|js&t|jDcgc]}|duc}r t|jr(|dj d|jDdzz }t |jD]q\}}||jdzz }|j|r&|j|D]}|d|jzz }|t|jdz ksm|dz }st|jr\|ddj tt|jzz }n,|dj tt|jz }|dz }|Scc}w)Npos rc3<K|]}|jywrrrOrs rQrRz1ChainContextPosStatement.asFea..?a ?rNr^ lookup rr4 rrUrVanyr{rSr_rrrrrrrrarrlus rQrzChainContextPosStatement.asFeaN  4;;4<<8aATM894;;sxx?4;;??#EE!$++. 1qwwy3&<<?"ll1o4zBGG334s4;;'!++3JC  4;;sSXXc%&=>>> 388Ct{{34 4C s  !9 FrrrrNrVrQr r   / rVr c&eZdZdZddZdZddZy)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.Nctj|||||c|_|_|_t ||_t|D]\}}|s t|y#t$r|g|j |<Y3wxYwrrzr~s rQrz#ChainContextSubstStatement.__init__rrc^|jDcgc]}|j}}|jDcgc]}|j}}|jDcgc]}|j}}|j |j ||||j ycc}wcc}wcc}w)z9Calls the builder's ``add_chain_context_subst`` callback.N)rUrrrVadd_chain_context_substrr{rs rQrz ChainContextSubstStatement.builds(, 41!**,44(, 41!**,44(, 41!**,44'' MM6664<< 544rc,d}t|js;t|js&t|jDcgc]}|duc}r t|jr(|dj d|jDdzz }t |jD]q\}}||jdzz }|j|r&|j|D]}|d|jzz }|t|jdz ksm|dz }st|jr\|ddj tt|jzz }n,|dj tt|jz }|dz }|Scc}w)Nr]rc3<K|]}|jywrrrs rQrRz3ChainContextSubstStatement.asFea.."rrNr^rrr4rrs rQrz ChainContextSubstStatement.asFearrrrrrNrVrQr!r!rrVr!c&eZdZdZddZdZddZy)r$znA cursive positioning statement. Entry and exit anchors can either be :class:`Anchor` objects or ``None``.Nc\tj||||_||c|_|_yr)rBrr entryAnchor exitAnchor)rrrrrs rQrzCursivePosStatement.__init__6s*4*$,7)$/rVc|j|j|jj|j|j y)z8Calls the builder object's ``add_cursive_pos`` callback.N)add_cursive_posrrrrrrs rQrzCursivePosStatement.build;s4 MM4??335t7G7G rVc|jr|jjnd}|jr|jjnd}dj|jj||S)N zpos cursive {} {} {};)rrrrr)rrentryexits rQrzCursivePosStatement.asFeaAs\,0,<,<  &&(/*.//t$$&&--doo.C.C.EudSSrVrrrrNrVrQr$r$2s/D  TrVr$c&eZdZdZddZdZddZy)r)zExample: ``feature salt;``NcNtj||||c|_|_yr)rBrr featureName)rrrs rQrz"FeatureReferenceStatement.__init__Js#4*+3[' t'rVcP|j|j|jy)z>Calls the builder object's ``add_feature_reference`` callback.N)add_feature_referencerrrs rQrzFeatureReferenceStatement.buildNs%%dmmT5E5EFrVc8dj|jS)Nz feature {};)rrrs rQrzFeatureReferenceStatement.asFeaRs##D$4$455rVrrrrNrVrQr)r)Gs$BG6rVr)c&eZdZdZddZdZddZy)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`_ .Nc>tj||||_yrrBr chainContextsrrrs rQrzIgnorePosStatement.__init__]4**rVc8|jD]|\}}}|Dcgc]}|j}}|Dcgc]}|j}}|Dcgc]}|j}}|j|j|||g~ycc}wcc}wcc}w)z[Calls the builder object's ``add_chain_context_pos`` callback on each rule context.N)rrrrrrrUrrVr[rrs rQrzIgnorePosStatement.buildas'+&8&8 U "FFF,23qajjl3F3,23qajjl3F3,23qajjl3F3  ) )$--QS T  U333B BBc g}|jD]\}}}d}t|s t|r|t|r%|djtt|dzz }|djd|Dz }t|rH|ddjtt|zz }n"|djtt|z }|j |ddj|zdzS)Nrrc3BK|]}|jdzywr^Nrrs rQrRz+IgnorePosStatement.asFea..qs@A C@z ignore pos rLr4rrrSrrrrrcontextsrUrrVrs rQrzIgnorePosStatement.asFeajs&*&8&8 ! "FFFC6{c&kv;388Cv$67#==Csxx@@@@v;3#eV*tj||||_yrrrs rQrzIgnoreSubstStatement.__init__rrVc8|jD]|\}}}|Dcgc]}|j}}|Dcgc]}|j}}|Dcgc]}|j}}|j|j|||g~ycc}wcc}wcc}w)z]Calls the builder object's ``add_chain_context_subst`` callback on each rule context.N)rrrrrs rQrzIgnoreSubstStatement.builds'+&8&8 W "FFF,23qajjl3F3,23qajjl3F3,23qajjl3F3  + +DMM666SU V  W333rc zg}|jD]\}}}d}t|r%|djtt|dzz }|djd|Dz }t|r%|ddjtt|zz }|j |ddj|zdzS)Nrrc3BK|]}|jdzywrrrs rQrRz-IgnoreSubstStatement.asFea..s<AGGIOtj||||_yr)rBrrevision)rrrs rQrzFontRevisionStatement.__init__s4*  rVcP|j|j|jyr)set_font_revisionrrrs rQrzFontRevisionStatement.builds!!$--?rVc8dj|jS)NzFontRevision {:.3f};)rrrs rQrzFontRevisionStatement.asFeas%,,T]];;rVrrrrNrVrQr*r*sJ!@.)FQ#a&)FrwrrrrSrrs rQrz#LigatureCaretByIndexStatement.asFeas:,33 KK   )F$++)F!F  rVrrrrNrVrQr1r1sR4S  rVr1c&eZdZdZddZdZddZy)r2zA ``GDEF`` table ``LigatureCaretByPos`` statement. ``glyphs`` should be a `glyph-containing object`_, and ``carets`` should be a list of integers.NcNtj||||c|_|_yrrrs rQrz$LigatureCaretByPosStatement.__init__rrVc|jj}|j|j|t |j y)z@Calls the builder object's ``add_ligatureCaretByPos_`` callback.N)rradd_ligatureCaretByPos_rrrrqs rQrz!LigatureCaretByPosStatement.builds3%%''' vs4;;?OPrVcdj|jjdjd|jDS)NzLigatureCaretByPos {} {};rc32K|]}t|ywrrtrs rQrRz4LigatureCaretByPosStatement.asFea.. rrwrrs rQrz!LigatureCaretByPosStatement.asFea s:*11 KK   )F$++)F!F  rVrrrrNrVrQr2r2sR4Q  rVr2c&eZdZdZddZdZddZy)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.Ncztj|||||c|_|_|_||c|_|_yr)rBrrUrrVrW forceChain)rrUrrVrWrrs rQrzLigatureSubstStatement.__init__s94*17- T[$+,7)$/rVct|jDcgc]}|j}}|jDcgc]}|j}}|jDcgc]}|j}}|j |j ||||j |jycc}wcc}wcc}wr)rUrrrVadd_ligature_substrrWrrs rQrzLigatureSubstStatement.builds(, 41!**,44(, 41!**,44(, 41!**,44"" MM66643C3CT__ 544sB+B0B5cDd}t|js!t|js |jrt|jr(|dj d|jDdzz }|dj d|j Dz }t|jrN|ddj d|jDzz }n%|dj d|j Dz }|dz }|t |jz }|dz }|S) Nr]rc3<K|]}|jywrrrs rQrRz/LigatureSubstStatement.asFea..*rrNc3BK|]}|jdzywrrrs rQrRz/LigatureSubstStatement.asFea..+sAAGGIOArc3<K|]}|jywrrrs rQrRz/LigatureSubstStatement.asFea..-s%EAaggi%ErNc3<K|]}|jywrrrs rQrRz/LigatureSubstStatement.asFea../s;!AGGI;rN by r4)rrUrVrrSrrrWrs rQrzLigatureSubstStatement.asFea&s t{{ s4;;/4??4;;sxx?4;;??#EE 388AT[[AA AC4;;sSXX%E%EEEE 388;t{{;; ;C v  uT%%&& s  rVrrrrNrVrQr3r3sBD   rVr3c(eZdZdZ ddZdZddZy)r4zA ``lookupflag`` statement. The ``value`` should be an integer value representing the flags in use, but not including the ``markAttachment`` class and ``markFilteringSet`` values, which must be specified as glyph-containing objects.NcZtj||||_||_||_yr)rBrrmarkAttachmentmarkFilteringSet)rrrrrs rQrzLookupFlagStatement.__init__<s+ 4* , 0rVcd}|j|jj}d}|j|jj}|j|j|j ||y)z8Calls the builder object's ``set_lookup_flag`` callback.N)rrrset_lookup_flagrr)rr markAttach markFilters rQrzLookupFlagStatement.buildDsh    *,,557J  ,..779J tzz:zRrVcg}gd}d}tt|D]-}|j|zdk7r|j|||dz}/|j8|jdj |jj |j8|jdj |jj |sdg}dj dj|S) N) RightToLeftIgnoreBaseGlyphsIgnoreLigatures IgnoreMarksrrzMarkAttachmentType {}zUseMarkFilteringSet {}0zlookupflag {};r) rangerrrrrrrrS)rrrflagsrrs rQrzLookupFlagStatement.asFeaNsUs5z" AzzD A% 58$19D     * JJ.55d6I6I6O6O6QR S  , JJ/66t7L7L7R7R7TU V%C&&sxx}55rV)rNNNrrrNrVrQr4r46s! MQ1S6rVr4c&eZdZdZddZdZddZy)r5zRepresents a ``lookup ...;`` statement to include a lookup in a feature. The ``lookup`` should be a :class:`LookupBlock` object.NcNtj||||c|_|_yr)rBrrrm)rrmrs rQrz!LookupReferenceStatement.__init__ds"4*&." t{rVcN|j|jjy)z8Calls the builder object's ``add_lookup_call`` callback.N)add_lookup_callrmrrs rQrzLookupReferenceStatement.buildhs 0 01rVcLdj|jjS)Nz lookup {};)rrmrrs rQrzLookupReferenceStatement.asFeals""4;;#3#344rVrrrrNrVrQr5r5_s?825rVr5c&eZdZdZddZdZddZy)r6zA mark-to-base positioning rule. The ``base`` should be a `glyph-containing object`_. The ``marks`` should be a list of (:class:`Anchor`, :class:`MarkClass`) tuples.NcNtj||||c|_|_yr)rBrrmarks)rrr rs rQrzMarkBasePosStatement.__init__us"4* $e 4:rVc|j|j|jj|jy)z:Calls the builder object's ``add_mark_base_pos`` callback.N)add_mark_base_posrrrr rs rQrzMarkBasePosStatement.buildys)!!$--1C1C1EtzzRrVcdj|jj}|jD]?\}}|d|ztzdj|j|j zz }A|dz }|S)Nz pos base {}r {} mark @{}r4)rrrr rrrrrams rQrzMarkBasePosStatement.asFea}ss""499??#45JJ SDAq 4&=5(=+?+? 166+RR RC S s  rVrrrrNrVrQr6r6ps5,SrVr6c&eZdZdZddZdZddZy)r7aA mark-to-ligature positioning rule. The ``ligatures`` must be a `glyph-containing object`_. The ``marks`` should be a list of lists: each element in the top-level list represents a component glyph, and is made up of a list of (:class:`Anchor`, :class:`MarkClass`) tuples representing mark attachment points for that position. Example:: m1 = MarkClass("TOP_MARKS") m2 = MarkClass("BOTTOM_MARKS") # ... add definitions to mark classes... glyph = GlyphName("lam_meem_jeem") marks = [ [ (Anchor(625,1800), m1) ], # Attachments on 1st component (lam) [ (Anchor(376,-378), m2) ], # Attachments on 2nd component (meem) [ ] # No attachments on the jeem ] mlp = MarkLigPosStatement(glyph, marks) mlp.asFea() # pos ligature lam_meem_jeem mark @TOP_MARKS # ligComponent mark @BOTTOM_MARKS; NcNtj||||c|_|_yr)rBr ligaturesr )rrr rs rQrzMarkLigPosStatement.__init__"4*%." rVc|j|j|jj|jy)z9Calls the builder object's ``add_mark_lig_pos`` callback.N)add_mark_lig_posrrrr rs rQrzMarkLigPosStatement.builds)  0G0G0I4::VrVcdj|jj}g}|jD]|}d}| t |sd|zt dzzdz}nG|D]B\}}|d|zt dzzdj|j|j zz }D|j|~|d|zt zdzj|z }|dz }|S) Nzpos ligature {}rrrrr ligComponentr4) rrrr rrrrrS)rrrligsltemprrs rQrzMarkLigPosStatement.asFeas&&t~~';';'=> ADyAf}uqy0?BDAq !!)$(..qwwy!&&ABD KK   v %6<>#7#7#9:JJ SDAq 4&=5(=+?+? 166+RR RC S s  rVrrrrNrVrQr8r8s56XrVr8c(eZdZdZ ddZdZddZy)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. Ncxtj|||||c|_|_|_||_||_yr)rBrrUrrVrWr)rrUrrVrWrrs rQrzMultipleSubstStatement.__init__s9 4*/5uf, TZ&$rVc |jDcgc]}|j}}|jDcgc]}|j}}t|jdr|jj}n |jg}t |}g}|j D]T} t| dr| j} n| g} t | dk(rt | |k7r| |z} |j| Vtt|}t} t|D]P\} } | | vs | j| |j|j|| ||xr|| xsd|jRycc}wcc}w)z;Calls the builder object's ``add_multiple_subst`` callback.rrrNN)rUrrVrrrrWrrYziprr_addadd_multiple_substrr)rrr[rUrrV originalscountreplacesrreplaceseen_originalsrrs rQrzMultipleSubstStatement.buildsU(, 41!**,44(, 41!**,44 4::z * ++-I II!! %Aq*%**,#7|q S\U%:!E/ OOG $ %X'$Y/ KAx~-""8,**MM,!2OO  '54s E7E<cxd}t|js!t|js |jrt|jr/|dj t t |jdzz }|t |jdzz }t|jrH|ddj t t |jzz }n|t |jz }|jxs tg}|dz }|dj t t |z }|dz }|S)Nr]rr^rr4) rrUrVrrSrrrrWr)rrrrWs rQrzMultipleSubstStatement.asFeas t{{ s4;;/4??4;;sxxE4;; 783>> 5$s* *C4;;sSXXc%&=>>> 5$ $C&&79;-  v  sxxE;/00 s  rVrrrrNrVrQr9r9s NR%BrVr9c*eZdZdZ ddZdZddZy)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 `_. Ncztj||||_||c|_|_||c|_|_yr)rBr enumeratedglyphs1 valuerecord1glyphs2 valuerecord2)rr4r5r6r7r3rs rQrzPairPosStatement.__init__"s= 4*$*1<' d'*1<' d'rVcF|jr|jj|jjg}d}t j |D]:\}}d}|j |j||j||j<|std|jyt|jtxrt|jt}|r\|j |j|jj|j|jj|jy|j|j|jj|j|jj|jy)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)r3r4rr6 itertoolsproductadd_specific_pair_posrr5r7rrr radd_class_pair_pos)rrr seen_pairglyph1glyph2 is_specifics rQrzPairPosStatement.build0sT ??&&($,,*?*?*ABAI"+"3"3Q"7  --MM64+<+.sBQaBrwc38K|]}t|dzywrrrs rQrRz9ReverseChainSingleSubstStatement.asFea..@qE!HsN@c32K|]}t|ywrrrs rQrRz9ReverseChainSingleSubstStatement.asFea..s%H1eAh%Hrw by {};c32K|]}t|ywrrrs rQrRz9ReverseChainSingleSubstStatement.asFea..(Maq(Mrw) rrDrErSrrrrrFrs rQrz&ReverseChainSingleSubstStatement.asFeas t 3t#74??#sxxB$//BBSHH 388@DKK@@ @C4??#sSXX%H%HHHH 388Ct{{34 4C y(M4;L;L(M MNN rVrrrrNrVrQr=r=ks)   rVr=c&eZdZdZddZdZddZy)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. Ncxtj||||c|_|_||_||_||_yr)rBrrUrVrrrF)rrr.rUrVrrs rQrzSingleSubstStatement.__init__s84*#)6  T[$ #rVc |jDcgc]}|j}}|jDcgc]}|j}}|jdj}|jdj}t |dk(r|t |z}|j |j||tt|||jycc}wcc}w)z9Calls the builder object's ``add_single_subst`` callback.rrN) rUrrVrrFradd_single_substrrr'rrJs rQrzSingleSubstStatement.builds(, 41!**,44(, 41!**,44KKN++- $$Q'002 x=A #i.0H  MM   Ix0 1 OO  54s C"C'chd}t|js!t|js |jrt|jr(|dj d|jDdzz }|dj d|j Dz }t|jrN|ddj d|jDzz }n%|dj d|j Dz }|dj dj d|jDz }|S) Nr]rc32K|]}t|ywrrrs rQrRz-SingleSubstStatement.asFea..s>Qa>rwc38K|]}t|dzywrrrs rQrRz-SingleSubstStatement.asFea..rNrOc32K|]}t|ywrrrs rQrRz-SingleSubstStatement.asFea..s%D1eAh%Drwc32K|]}t|ywrrrs rQrRz-SingleSubstStatement.asFea..s:E!H:rwrQc32K|]}t|ywrrrs rQrRz-SingleSubstStatement.asFea..rSrw)rrUrVrrSrrrFrs rQrzSingleSubstStatement.asFeas t{{ s4;;/4??4;;sxx>$++>>DD 388@DKK@@ @C4;;sSXX%D %DDDD 388:dkk:: :C y(M4;L;L(M MNN rVrrrrNrVrQr@r@s$ rVr@c&eZdZdZddZdZddZy)r>zA ``script`` statement.Nc>tj||||_yr)rBrr{)rr{rs rQrzScriptStatement.__init__s4* rVcP|j|j|jy)z,Calls the builder's ``set_script`` callback.N) set_scriptrr{rs rQrzScriptStatement.builds4==$++6rVcTdj|jjS)Nz script {};)rr{rrs rQrzScriptStatement.asFeas ""4;;#4#4#677rVrrrrNrVrQr>r>s!78rVr>c&eZdZdZddZdZddZy)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.Ncjtj|||||c|_|_|_||_yr)rBrrurUrVr)rrurUrVrrs rQrzSinglePosStatement.__init__s/4*-0&&*$+t{$rVcn|jDcgc]}|j}}|jDcgc]}|j}}|jDcgc]\}}|j|f}}}|j |j ||||j ycc}wcc}wcc}}w)z7Calls the builder object's ``add_single_pos`` callback.N)rUrrVruadd_single_posrr) rrr[rUrrVrrrus rQrzSinglePosStatement.builds(, 41!**,44(, 41!**,4459XX>E e$>>t}}ffc4??S54>sB'B,B1c d}t|js!t|js |jrt|jr/|dj t t |jdzz }|dj |jDcgc]1}t |ddz|dd|dj zndz3c}z }t|jr|ddj t t |jzz }nV|dj |jDcgc].}t |ddz|d|dj ndz0c}z }|dz }|Scc}wcc}w)Nrrrr^rrr4)rrUrVrrSrrru)rrrras rQrzSinglePosStatement.asFeas\ t{{ s4;;/4??4;;sxxE4;; 783>> 388 "XX !A$K/0t/?adjjl*RI C4;;sSXXc%&=>>> 388"XX!A$K#%19I1rR C s  #s 6E8 53E= rrrrNrVrQr?r?s$ % TrVr?c&eZdZdZddZdZddZy)rFzRepresents a subtable break.Nc0tj||yr)rBrrs rQrzSubtableStatement.__init__s4*rVc:|j|jy)zr.hs%   D! D (  s)rorprqrrrsrtrurv)rrs`rQ__bool__zValueRecord.__bool__gs      rV) NNNNNNNNFNr) rrrrrr{r}rrr __nonzero__rNrVrQrHrH sK$!( &  * X  KrVrHc eZdZdZddZddZy)rIz+Represents a named value record definition.NcLtj||||_||_yr)rBrrr)rrrrs rQrzValueRecordDefinition.__init__|s 4*  rVcjdj|jj|jS)NzvalueRecordDef {} {};)rrrrrs rQrzValueRecordDefinition.asFeas&&--djj.>.>.@$))LLrVrrrrNrVrQrIrIys5 MrVrIch|dk(r |dk(r|dk(ry|dk(r |dk(r|dk(rydj|||S)Nri rr1{} {} {}r)pideidlids rQsimplify_name_attributesrsC axC1H cQh3!8  c3//rVc&eZdZdZddZdZddZy)r:zRepresents a name record. (`Section 9.e. `_)Ncvtj||||_||_||_||_||_yr)rBrnameID platformID platEncIDlangIDstring)rrrrrrrs rQrzNameRecord.__init__s54* $"  rVc|j|j|j|j|j|j |j y)z8Calls the builder object's ``add_name_record`` callback.N)add_name_recordrrrrrrrs rQrzNameRecord.builds: MM KK OO NN KK KK  rVc d}t|j|j|j}|t d|j t |j|}|dk(r\djtdt|dDcgc],}|t||dzt||d zzd .c}}n/dj|Dcgc]}|t|d c}}t|j|j|j}|dk7r|d z }d j|j||Scc}wcc}w)Nc>|dk\r|dkr|dvr t|S||zS)N ~)"\)chr)rvescape_patterns rQescapez NameRecord.asFea..escapes*DyQ$Y1L+@1v %))rVzUnsupported encoding)encoding utf_16_berrrrz\%04xz\%02xrznameid {} {}"{}";)rrrrrrrrrSrrrrrr) rrrrrrescaped_stringbplats rQrzNameRecord.asFeas  *t L  !"8$--H H DKK( 3 { "WW#1c!fa071Q4=3.1q51BBHMN WWA%NqfWQZ&B%NON'U 2: CKD"))$++t^LL &Os 1EErrrrNrVrQr:r:sK  MrVr:ceZdZdZdZddZy)r(z4Represents a ``sizemenuname`` or ``name`` statement.cftj|||j|jy)z8Calls the builder object's ``add_featureName`` callback.N)r:radd_featureNamerrs rQrzFeatureNameStatement.builds$w' ,rVc|jdk(rd}nd}t|j|j|j}|dk7r|dz }dj |||j S)Nsize sizemenunamerrrz {} {}"{}";)rrrrrrr)rrrrs rQrzFeatureNameStatement.asFeas[ ;;&  CC'U 2: CKD""3dkk::rVNr)rrrrrrrNrVrQr(r(s>- ;rVr(ceZdZdZddZy)rEz+Represents a STAT table ``name`` statement.ct|j|j|j}|dk7r|dz }dj ||j SNrrz name {}"{}";rrrrrrrrrs rQrzSTATNameStatement.asFeaC'U 2: CKD$$T4;;77rVNr)rrrrrrNrVrQrErEs 58rVrEc&eZdZdZddZdZddZy)rAzA ``parameters`` statement.Nchtj||||_||_||_||_yr)rBr DesignSize SubfamilyID RangeStartRangeEnd)rrrrrrs rQrzSizeParameters.__init__s/4*$&$  rVc|j|j|j|j|j|j y)zUV VCSyrVrrrrNrVrQrArAs%! rVrAc(eZdZdZ ddZdZddZy)rz;Represent a name statement inside a ``cvParameters`` block.Nc Jtj|||||||||_yr)r:rr")rrrrrrr"rs rQrz"CVParametersNameStatement.__init__s/  &*i(  %rVc2d}|jdk(r5dj|jj|jd}|j |j|j|j|zf|_t j||y)z9Calls the builder object's ``add_cv_parameter`` callback.rr$z_{}rN)r"rcv_num_named_params_getradd_cv_parameterr:r)rritems rQrzCVParametersNameStatement.buildst ??2 2<< < < @ @a PQD  -{{DOOd$:; w'rVct|j|j|j}|dk7r|dz }dj ||j Srrrs rQrzCVParametersNameStatement.asFea rrVrrrrNrVrQrrsESW%(8rVrc&eZdZdZddZdZddZy)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. NcLtj||||_||_yr)rBr characterr)rrrrs rQrzCharacterStatement.__init__s 4*"rVcP|j|j|jy)z9Calls the builder object's ``add_cv_character`` callback.N)add_cv_characterrrrs rQrzCharacterStatement.builds  :rVc8dj|jS)NzCharacter {:#x};)rrrs rQrzCharacterStatement.asFea#s!((88rVrrrrNrVrQr"r"s ;9rVr"c&eZdZdZddZdZddZy)rzAn axis definition, being either a ``VertAxis.BaseTagList/BaseScriptList`` pair or a ``HorizAxis.BaseTagList/BaseScriptList`` pair.Nchtj||||_||_||_g|_yr)rBrbasesscriptsrwminmax)rrrrwrrs rQrzBaseAxis.__init__+s.4*     rVc||j|j|j|j|jy)z6Calls the builder object's ``set_base_axis`` callback.N) set_base_axisrrrwrrs rQrzBaseAxis.build2s&djj$,, t{{SrVc|jrdnd}|jDcgc];}dj|d|ddjt t |d=}}|j Dcgc]#}dj||d|d|d|d %}}d j|dj|j||d j|d j|zScc}wcc}w) NVertHorizrrrrrz {}Axis.MinMax {} {} {}, {};rz2{}Axis.BaseTagList {}; {}{}Axis.BaseScriptList {};rLr)rwrrrSrrurr)rr directionrrminmaxess rQrzBaseAxis.asFea6s"mmF \\    adAaD#((3sAaD>*B C  [[  , 2 29adAaD!A$PQRSPT U  EKK sxx +VY '@R IIh     s AC(/(C-rrrrNrVrQrr's@T  rVrc&eZdZdZddZdZddZy)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.NcLtj||||_||_yrrBrrrrrrrs rQrzOS2Field.__init__J 4* rVcP|j|j|jy)z6Calls the builder object's ``add_os2_field`` callback.N) add_os2_fieldrrrs rQrzOS2Field.buildOsdhh 3rVcd}d}d}t|Dcgc]}|j|tgfc}}|j|Dcgc]}|j||gfc}d|g|d<ddg|d<|j|vrBd j ||jd ||jd |j Sy cc}wcc}w) Nc@djtt|S)Nr)rSrru)ras rQ intarr2strz"OS2Field.asFea..intarr2strTs88CQK( (rV) FSType TypoAscender TypoDescender TypoLineGap winAscent winDescentXHeight CapHeight WeightClass WidthClass LowerOpSize UpperOpSize) UnicodeRange CodePageRangePanosepanoseVendorc$dj|S)Nz"{}"r)rbs rQz OS2Field.asFea..is&--2BrVvendor{} {};rrr)rIrruupdaterrr)rrrnumbersrangesrakeywordss rQrzOS2Field.asFeaSs )  3@1!'')aX.@AvF!!'')a_5FG& 3&(BC 88x ??"1%'>9ArrrrNrVrQr+r+q) 5?rVr+c&eZdZdZddZdZddZy)rJzAn entry in the ``vhea`` table.NcLtj||||_||_yrrrs rQrzVheaField.__init__rrVcP|j|j|jy)z7Calls the builder object's ``add_vhea_field`` callback.N)add_vhea_fieldrrrs rQrzVheaField.buildrrVcd}t|Dcgc]}|j|fc}}dj||j|jScc}w)N)VertTypoAscenderVertTypoDescenderVertTypoLineGaprr r s rQrzVheaField.asFeasIM8A!'')Q89x14::>>9rrrrrNrVrQrJrJrrVrJc&eZdZdZddZdZddZy)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 Nchtj||||_||_||_||_yr)rBrr axisOrdernamesr)rrrrrs rQrz STATDesignAxisStatement.__init__s.4*"   rVc<|j||jyr) addDesignAxisrrs rQrzSTATDesignAxisStatement.buildsdDMM2rVc |tz }d|jd|jd}|d|zj|jDcgc]}|j |c}dzz }|dz }|Scc}w)Nz DesignAxis rz { rr};)rrrrSrrrrrrs rQrzSTATDesignAxisStatement.asFeasu%DHH:Qt~~&6f= v ##TZZ$PQWWFW%;$PQTXXX t  %QsA0 rrrrNrVrQrDrDs!3rVrDc&eZdZdZddZdZddZy)r%ziSTAT table ElidedFallbackName Args: names: a list of :class:`STATNameStatement` objects NcLtj||||_||_yr)rBrrr)rrrs rQrzElidedFallbackName.__init__ 4*   rVcP|j|j|jyr)setElidedFallbackNamerrrs rQrzElidedFallbackName.build%%djj$--@rVc |tz }d}|d|zj|jDcgc]}|j|c}dzz }|dz }|Scc}w)NzElidedFallbackName { rrr)rrSrrr s rQrzElidedFallbackName.asFeas]%' v ##TZZ$PQWWFW%;$PQTXXX t  %QsA rrrrNrVrQr%r%s ! ArVr%c&eZdZdZddZdZddZy)r&zpSTAT table ElidedFallbackNameID Args: value: an int pointing to an existing name table name ID NcLtj||||_||_yr)rBrrr)rrrs rQrzElidedFallbackNameID.__init__r#rVcP|j|j|jyr)r%rrrs rQrzElidedFallbackNameID.buildr&rVc"d|jdS)NzElidedFallbackNameID r4)rrs rQrzElidedFallbackNameID.asFeas&tzzl!44rVrrrrNrVrQr&r&s ! A5rVr&c&eZdZdZddZdZddZy)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 NcZtj||||_||_||_yr)rBrr locationsr)rrr.rrs rQrzSTATAxisValueStatement.__init__s'4* " rVc<|j||jyr)addAxisValueRecordrrs rQrzSTATAxisValueStatement.builds""47rVcd}|jD]}||jz }|jD]}||jz }|dz }|jrdddg}g}d}t t |D]-}|j|zdk7r|j |||dz}/|ddj|d z }|d z }|S) Nz AxisValue { rOlderSiblingFontAttributeElidableAxisValueNamerrzflag r; r)r.rrrrrrrS) rrrr nameRecordr flagStringsrrs rQrzSTATAxisValueStatement.asFeas $H 8>># #C $** J :##% %C 4KC  ::02IJEKD3u:& !::$)&&uQx0qy ! U388K015 5C t  rVrrrrNrVrQrCrCs 8rVrCc eZdZdZddZddZy)rz A STAT table Axis Value Location Args: tag (str): a 4 letter axis tag values (list): a list of ints and/or floats NcLtj||||_||_yr)rBrrvalues)rrr9rs rQrz#AxisValueLocationStatement.__init__ s 4* rVc||d|jdz }|djd|jDdz }|S)Nz location rc32K|]}t|ywrrt)rOrs rQrRz3AxisValueLocationStatement.asFea..s7a3q67rwr4)rrSr9)rrs rQrz AxisValueLocationStatement.asFeasC 488*A&& #((74;;778<< rVrrrrNrVrQrrs rVrc&eZdZdZddZdZddZy)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. NcLtj||||_||_yr)rBrr conditions)rrr>rs rQrzConditionsetStatement.__init__ s 4* $rVcf|j|j|j|jyr)add_conditionsetrrr>rs rQrzConditionsetStatement.build%s    4??KrVc ||d|jdzdzz }|jjD] \}\}}||tz|d|d|dzz }"||dzd|jdzz }|S)Nz conditionset rrr4})rr>rr)rrrrminvaluemaxvalues rQrzConditionsetStatement.asFea(s v- {!44u<<)-)>)>)@ F %C%(H 6E>se1XJaz$EE EC F v|$))C000 rVr)rrrrNrVrQr#r#s% LrVr#c&eZdZdZddZdZddZy)VariationBlockzCA variation feature block, applicable in a given set of conditions.Nc\tj|||||c|_|_|_yr)rrr conditionsetr )rrrHr rs rQrzVariationBlock.__init__3s, tX&    9 4$d&8rVc`|j|j|j|j|jdk7r;|j|j vr#t d|j|j|j}i|_tj|||jjD]V\}}|jj|ij|jg}|j|||vsRg||<X||_|jy)rrz,variation block used undefined conditionset N)rrrr rHconditionsets_rrrrrfeature_variations_rrr)rrrrrrs rQrzVariationBlock.build;s dmmTYY8J8JK    '!!)?)??!>t?P?P>QR  $$ D'"!++113 #JC//::3CNN!!2E LL (" "  #%rVc|d|jjzz}||jdzz }|jr|dz }|dz }|tj ||z }||d|jjzzz }|S)Nz variation %s rrrrr)rrrHr rrrs rQrzVariationBlock.asFeaWs)::: t  3&&    ? "C u  u{{4{// v DIIOO$5555 rVrrrrNrVrQrFrF0sM 8rVrF)YrDfontTools.feaLib.errorrfontTools.feaLib.locationrfontTools.misc.encodingToolsrfontTools.misc.textToolsrr collectionsrr9r__all__rUrrrobjectr 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#rFrNrVrQrTs2845#C LF57 tf,     g    ! ! ;%;%|*Z*")J)" Y  I . J% J5>%*%,   C9 C  Y <**Z$ )$ N"i"J"Z"J y  i &7y7t77tT)T* 6 6!9!9H999B7y7& : Ri R