Warning: session_start(): Session cannot be started after headers have already been sent in /home/tvrreohg/public_html/manga.php on line 13
3 2j A@s~ddlmZddlmZddlmZddlmZmZddl m Z ddl Z dZ d d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFdGdHdIgAZ dJdKZedLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dg4ZddZGdd d eZGddAdAeZGdd&d&eZGdd d eZGdddeZGdd d eZGdd d eZGdddeZGdddeZGdddeZGdddeZGdd d eZGdddeZGdddeZ GdddeZ!GddFdFeZ"GdddeZ#GdddeZ$GdddeZ%GdddeZ&GdddeZ'GdddeZ(GdddeZ)GdddeZ*Gdd d eZ+Gdd!d!eZ,Gdd#d#eZ-Gdd(d(eZ.Gdd+d+eZ/Gdd,d,eZ0Gdd-d-eZ1Gdd.d.eZ2Gdd/d/eZ3Gdd)d)eZ4Gdd0d0eZ5Gdd1d1eZ6Gdd2d2eZ7Gdd3d3eZ8Gdd4d4eZ9Gdd5d5eZ:Gdd6d6eZ;Gdd7d7eZGdd<dd>eZBGddEdEeZCGddGdGeZDGddHdHeZEddZFGdd9d9eZGGdd'd'eGZHGddDdDeGZIGdd@d@eZJGdddeGZKGdd"d"eZLGdddeZMGdd:d:eZNGdd*d*eZOGddIdIeZPGddCdCeZQGdd$d$eZRGdd%d%eZSGddBdBeZTGdddeZUdS))FeatureLibError)FeatureLibLocation) getEncoding)byteordtobytes) OrderedDictN Element FeatureFileComment GlyphName GlyphClassGlyphClassName MarkClassNameAnonymousBlockBlock FeatureBlock NestedBlock LookupBlockGlyphClassDefinitionGlyphClassDefStatement MarkClassMarkClassDefinitionAlternateSubstStatementAnchorAnchorDefinitionAttachStatementAxisValueLocationStatementBaseAxisCVParametersNameStatementChainContextPosStatementChainContextSubstStatementCharacterStatementCursivePosStatementElidedFallbackNameElidedFallbackNameID ExpressionFeatureNameStatementFeatureReferenceStatementFontRevisionStatement HheaFieldIgnorePosStatementIgnoreSubstStatementIncludeStatementLanguageStatementLanguageSystemStatementLigatureCaretByIndexStatementLigatureCaretByPosStatementLigatureSubstStatementLookupFlagStatementLookupReferenceStatementMarkBasePosStatementMarkLigPosStatementMarkMarkPosStatementMultipleSubstStatement NameRecordOS2FieldPairPosStatement ReverseChainSingleSubstStatementScriptStatementSinglePosStatementSingleSubstStatementSizeParameters StatementSTATAxisValueStatementSTATDesignAxisStatementSTATNameStatementSubtableStatement TableBlock ValueRecordValueRecordDefinition VheaFieldcCs(|dkr dSddjdd|DSdS)Nz z z, css|]}d|VqdS)z%d %dN).0trKrK9/tmp/pip-build-_d5lkt3n/fonttools/fontTools/feaLib/ast.py Ssz!deviceToString..)join)devicerKrKrNdeviceToStringOsrRanchorZ anchordefZanonZ anonymousZbyZcontourZcursiverQenum enumerateZ excludedfltZ exclude_dfltfeaturefromignoreZignorebaseglyphsZignoreligaturesZ ignoremarksincludeZ includedfltZ include_dfltlanguageZlanguagesystemlookupZ lookupflagmarkZmarkattachmenttypeZ markclassZnameidnull parameterspospositionrequiredZ righttoleftZ reversesubZrsubscriptsub substituteZsubtabletableZusemarkfilteringsetZ useextensionZvaluerecorddefbaseZgdefheadZhheanameZvheaZvmtxcCs`t|dr|jSt|trDt|dkrDt|ddt|dS|jtkrXd|S|SdS)NasFearz - \)hasattrri isinstancetuplelenlower fea_keywords)grKrKrNris  ric@s4eZdZdZd ddZddZd dd Zd d ZdS)r z8A base class representing "something" in a feature file.NcCs"|rt|t rt|}||_dS)N)rnrlocation)selfrtrKrKrN__init__szElement.__init__cCsdS)NrK)rubuilderrKrKrNbuildsz Element.buildcCstdS)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.N)NotImplementedError)ruindentrKrKrNrisz Element.asFeacCs|jS)N)ri)rurKrKrN__str__szElement.__str__)N)ry)__name__ __module__ __qualname____doc__rvrxrir|rKrKrKrNr s   c@s eZdZdS)rBN)r}r~rrKrKrKrNrBsc@s eZdZdS)r'N)r}r~rrKrKrKrNr'scs,eZdZdZdfdd Zd ddZZS) r zA comment in a feature file.Ncstt|j|||_dS)N)superr rvtext)rurrt) __class__rKrNrvszComment.__init__rycCs|jS)N)r)rur{rKrKrNrisz Comment.asFea)N)ry)r}r~rrrvri __classcell__rKrK)rrNr sc@s,eZdZdZd ddZddZd dd ZdS) NullGlyphz5The NULL glyph, used in glyph deletion substitutions.NcCstj||dS)N)r'rv)rurtrKrKrNrvszNullGlyph.__init__cCsfS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.rK)rurKrKrNglyphSetszNullGlyph.glyphSetrycCsdS)NZNULLrK)rur{rKrKrNriszNullGlyph.asFea)N)ry)r}r~rrrvrrirKrKrKrNrs rc@s,eZdZdZd ddZddZd dd ZdS) r z)A single glyph name, such as ``cedilla``.NcCstj||||_dS)N)r'rvglyph)rurrtrKrKrNrvs zGlyphName.__init__cCs|jfS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)r)rurKrKrNrszGlyphName.glyphSetrycCs t|jS)N)rir)rur{rKrKrNriszGlyphName.asFea)N)ry)r}r~rrrvrrirKrKrKrNr s c@sTeZdZdZdddZddZddd Zd d Zd d ZddZ ddZ ddZ dS)rz1A glyph class, such as ``[acute cedilla grave]``.NcCs.tj|||dk r|ng|_g|_d|_dS)Nr)r'rvglyphsoriginalcurr)rurrtrKrKrNrvs zGlyphClass.__init__cCs t|jS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)ror)rurKrKrNrszGlyphClass.glyphSetrycCsvt|jrX|jt|jkr>|jj|j|jdt|j|_ddjtt|jdSddjtt|jdSdS)N[r])rprrrextendrPmapri)rur{rKrKrNris   zGlyphClass.asFeacCs|jj|dS)z6Add a list of :class:`GlyphName` objects to the class.N)rr)rurrKrKrNrszGlyphClass.extendcCs|jj|dS)z4Add a single :class:`GlyphName` object to the class.N)rappend)rurrKrKrNrszGlyphClass.appendcCsT|jt|jkr(|jj|j|jd|jj||f|jj|t|j|_dS)aAdd a range (e.g. ``A-Z``) to the class. ``start`` and ``end`` are either :class:`GlyphName` objects or strings representing the start and end glyphs in the class, and ``glyphs`` is the full list of :class:`GlyphName` objects in the range.N)rrprrrr)rustartendrrKrKrN add_ranges  zGlyphClass.add_rangecCs`|jt|jkr(|jj|j|jd|jjdj|dj|f|jj|t|j|_dS)zAdd a range to the class by glyph ID. ``start`` and ``end`` are the initial and final IDs, and ``glyphs`` is the full list of :class:`GlyphName` objects in the range.Nz\{})rrprrrrformat)rurrrrKrKrN add_cid_ranges  zGlyphClass.add_cid_rangecCsT|jt|jkr(|jj|j|jd|jj||jj|jt|j|_dS)zNAdd glyphs from the given :class:`GlyphClassName` object to the class.N)rrprrrrr)rugcrKrKrN add_classs  zGlyphClass.add_class)NN)ry) r}r~rrrvrrirrrrrrKrKrKrNrs    c@s,eZdZdZd ddZddZd dd ZdS) rzyA glyph class name, such as ``@FRENCH_MARKS``. This must be instantiated with a :class:`GlyphClassDefinition` object.NcCs$tj||t|tst||_dS)N)r'rvrnrAssertionError glyphclass)rurrtrKrKrNrv&s zGlyphClassName.__init__cCst|jjS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rorr)rurKrKrNr+szGlyphClassName.glyphSetrycCs d|jjS)N@)rrh)rur{rKrKrNri/szGlyphClassName.asFea)N)ry)r}r~rrrvrrirKrKrKrNr"s c@s,eZdZdZd ddZddZd dd ZdS) rzA mark class name, such as ``@FRENCH_MARKS`` defined with ``markClass``. This must be instantiated with a :class:`MarkClass` object.NcCs$tj||t|tst||_dS)N)r'rvrnrr markClass)rurrtrKrKrNrv7s zMarkClassName.__init__cCs |jjS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rr)rurKrKrNr<szMarkClassName.glyphSetrycCs d|jjS)Nr)rrh)rur{rKrKrNri@szMarkClassName.asFea)N)ry)r}r~rrrvrrirKrKrKrNr3s c@s$eZdZdZdddZd ddZdS) rzAn anonymous data block.NcCstj||||_||_dS)N)rBrvtagcontent)rurrrtrKrKrNrvGs zAnonymousBlock.__init__rycCs*dj|j}||j7}|dj|j7}|S)Nz anon {} {{ z}} {}; )rrr)rur{resrKrKrNriLs  zAnonymousBlock.asFea)N)ry)r}r~rrrvrirKrKrKrNrDs c@s,eZdZdZd ddZddZd dd ZdS) rz,A block of statements: feature, lookup, etc.NcCstj||g|_dS)N)rBrv statements)rurtrKrKrNrvVs zBlock.__init__cCsx|jD]}|j|qWdS)zWhen handed a 'builder' object of comparable interface to :class:`fontTools.feaLib.builder`, walks the statements in this block, calling the builder callbacks.N)rrx)rurwsrKrKrNrxZs z Block.buildrycs.t7djfdd|jDdS)N csg|]}|jdqS))r{)ri)rLr)r{rKrN eszBlock.asFea..)SHIFTrPr)rur{rK)r{rNriasz Block.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrSs c@s"eZdZdZddZdddZdS) r zpThe top-level element of the syntax tree, containing the whole feature file in its ``statements`` attribute.cCstj|ddi|_dS)N)rt)rrvZ markClasses)rurKrKrNrvnszFeatureFile.__init__rycsdjfdd|jDS)Nrc3s|]}|jdVqdS))r{N)ri)rLr)r{rKrNrOssz$FeatureFile.asFea..)rPr)rur{rK)r{rNrirszFeatureFile.asFeaN)ry)r}r~rrrvrirKrKrKrNr jsc@s,eZdZdZd ddZddZd d d ZdS) rzA named feature block.FNcCstj|||||_|_dS)N)rrvrh use_extension)rurhrrtrKrKrNrvys zFeatureBlock.__init__cCsd|j|j|j|j}i|_tj||x(|jjD]\}}|j|gj|q4W||_|j dS)zCall the ``start_feature`` callback on the builder object, visit all the statements in this feature, and then call ``end_feature``.N) Z start_featurertrhZ features_rrxitems setdefaultrZ end_feature)rurwfeatureskeyvaluerKrKrNrx}s zFeatureBlock.buildrycCsT|d|jj}|jr |d7}|d7}|tj||d7}||d|jj7}|S)Nz feature %s z useExtension z{ )r{z} %s; )rhstriprrri)rur{rrKrKrNriszFeatureBlock.asFea)FN)ry)r}r~rrrvrxrirKrKrKrNrvs c@s,eZdZdZd ddZddZd dd ZdS) rzYA block inside another block, for example when found inside a ``cvParameters`` block.NcCstj||||_||_dS)N)rrvr block_name)rurrrtrKrKrNrvs zNestedBlock.__init__cCs&tj|||jdkr"|j|jdS)NParamUILabelNameID)rrxrZadd_to_cv_num_named_paramsr)rurwrKrKrNrxs  zNestedBlock.buildrycCs2dj||j}|tj||d7}|dj|7}|S)Nz{}{} {{ )r{z{}}}; )rrrri)rur{rrKrKrNriszNestedBlock.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrs c@s,eZdZdZd ddZddZd d d ZdS) rz*A named lookup, containing ``statements``.FNcCstj|||||_|_dS)N)rrvrhr)rurhrrtrKrKrNrvs zLookupBlock.__init__cCs(|j|j|jtj|||jdS)N)Zstart_lookup_blockrtrhrrxZend_lookup_block)rurwrKrKrNrxs zLookupBlock.buildrycCsJdj|j}|jr|d7}|d7}|tj||d7}|dj||j7}|S)Nz lookup {} z useExtension z{ )r{z {}}} {}; )rrhrrri)rur{rrKrKrNris zLookupBlock.asFea)FN)ry)r}r~rrrvrxrirKrKrKrNrs cs,eZdZdZdddZd fdd ZZS) rGzA ``table ... { }`` block.NcCstj||||_dS)N)rrvrh)rurhrtrKrKrNrvs zTableBlock.__init__rycs>dj|jj}|tt|j|d7}|dj|jj7}|S)Nz table {} {{ )r{z}} {}; )rrhrrrGri)rur{r)rrKrNriszTableBlock.asFea)N)ry)r}r~rrrvrirrKrK)rrNrGs c@s,eZdZdZd ddZddZd dd ZdS) rz!Example: ``@UPPERCASE = [A-Z];``.NcCstj||||_||_dS)N)rBrvrhr)rurhrrtrKrKrNrvs zGlyphClassDefinition.__init__cCst|jjS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rorr)rurKrKrNrszGlyphClassDefinition.glyphSetrycCsd|jd|jjdS)Nrz = ;)rhrri)rur{rKrKrNriszGlyphClassDefinition.asFea)N)ry)r}r~rrrvrrirKrKrKrNrs c@s,eZdZdZd ddZddZd dd ZdS) rzExample: ``GlyphClassDef @UPPERCASE, [B], [C], [D];``. The parameters must be either :class:`GlyphClass` or :class:`GlyphClassName` objects, or ``None``.NcCs*tj|||||_|_||_||_dS)N)rBrv baseGlyphs markGlyphsligatureGlyphscomponentGlyphs)rurrrrrtrKrKrNrvs zGlyphClassDefStatement.__init__cCsp|jr|jjnt}|jr&|jjnt}|jr<|jjnt}|jrR|jjnt}|j|j||||dS)z3Calls the builder's ``add_glyphClassDef`` callback.N)rrrorrrZadd_glyphClassDefrt)rurwrfZligar\comprKrKrNrxs zGlyphClassDefStatement.buildrycCsPdj|jr|jjnd|jr&|jjnd|jr8|jjnd|jrJ|jjndS)NzGlyphClassDef {}, {}, {}, {};ry)rrrirrr)rur{rKrKrNris zGlyphClassDefStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrs c@s2eZdZdZddZddZddZd d d Zd S) 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. cCs||_g|_t|_dS)N)rh definitionsrr)rurhrKrKrNrv szMarkClass.__init__cCs|t|tst|jj|x\|jD]P}||jkrj|j|j}|dkrLd}n d|}td||f|j||j|<q$WdS)z@Add a :class:`MarkClassDefinition` statement to this mark class.Nryz at zGlyph %s already defined%s) rnrrrrrrrtr)ruZ definitionrZotherLocrrKrKrN addDefinitions    zMarkClass.addDefinitioncCst|jjS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rorkeys)rurKrKrNr"szMarkClass.glyphSetrycCsdjdd|jD}|S)Nrcss|]}|jVqdS)N)ri)rLdrKrKrNrO'sz"MarkClass.asFea..)rPr)rur{rrKrKrNri&szMarkClass.asFeaN)ry)r}r~rrrvrrrirKrKrKrNrs  c@s,eZdZdZd ddZddZd dd ZdS) raA single ``markClass`` statement. The ``markClass`` should be a :class:`MarkClass` object, the ``anchor`` an :class:`Anchor` object, and the ``glyphs`` parameter should be a `glyph-containing object`_ . Example: .. code:: python mc = MarkClass("FRENCH_ACCENTS") mc.addDefinition( MarkClassDefinition(mc, Anchor(350, 800), GlyphClass([ GlyphName("acute"), GlyphName("grave") ]) ) ) mc.addDefinition( MarkClassDefinition(mc, Anchor(350, -200), GlyphClass([ GlyphName("cedilla") ]) ) ) mc.asFea() # markClass [acute grave] @FRENCH_ACCENTS; # markClass [cedilla] @FRENCH_ACCENTS; NcCsLtj||t|tstt|tr.t|ts2t||||_|_|_ dS)N) rBrvrnrrrr'rrSr)rurrSrrtrKrKrNrvBs zMarkClassDefinition.__init__cCs |jjS)zBThe glyphs in this class as a tuple of :class:`GlyphName` objects.)rr)rurKrKrNrHszMarkClassDefinition.glyphSetrycCsdj|jj|jj|jjS)NzmarkClass {} {} @{};)rrrirSrrh)rur{rKrKrNriLszMarkClassDefinition.asFea)N)ry)r}r~rrrvrrirKrKrKrNr+s c@s,eZdZdZd ddZddZd dd ZdS) rzA ``sub ... from ...`` statement. ``prefix``, ``glyph``, ``suffix`` and ``replacement`` should be lists of `glyph-containing objects`_. ``glyph`` should be a `one element list`.NcCs,tj||||||_|_|_||_dS)N)rBrvprefixrsuffix replacement)rurrrrrtrKrKrNrvXs z AlternateSubstStatement.__init__cCsl|jj}t|dkst|t|d}dd|jD}dd|jD}|jj}|j|j ||||dS)z5Calls the builder's ``add_alternate_subst`` callback.rkrcSsg|] }|jqSrK)r)rLprKrKrNrbsz1AlternateSubstStatement.build..cSsg|] }|jqSrK)r)rLrrKrKrNrcsN) rrrprlistrrrZadd_alternate_substrt)rurwrrrrrKrKrNrx]s   zAlternateSubstStatement.buildrycCsd}t|jst|jrtt|jr<|djtt|jd7}|t|jd7}t|jr|ddjtt|j7}n|t|j7}|d7}|t|j7}|d7}|S)Nzsub r'z from r)rprrrPrrirr)rur{rrKrKrNrigs  zAlternateSubstStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrRs  c@s$eZdZdZdddZd ddZdS) 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. NcCs:tj||||_||||_|_|_|||_|_dS)N)r'rvrhxy contourpoint xDeviceTable yDeviceTable)rurrrhrrrrtrKrKrNrv~s zAnchor.__init__rycCs|jdk rdj|jSdj|j|j}|jr<|dj|j7}|jsH|jrt|d7}|t|j7}|d7}|t|j7}|d7}|S)Nz z )rhrrrrrrrR)rur{rrKrKrNris   z Anchor.asFea)NNNNN)ry)r}r~rrrvrirKrKrKrNrws c@s$eZdZdZdddZd ddZdS) rzCA named anchor definition. (2.e.viii). ``name`` should be a string.NcCs,tj||||||f\|_|_|_|_dS)N)rBrvrhrrr)rurhrrrrtrKrKrNrvs zAnchorDefinition.__init__rycCs:dj|j|j}|jr&|dj|j7}|dj|j7}|S)NzanchorDef {} {}z contourpoint {}z {};)rrrrrh)rur{rrKrKrNris zAnchorDefinition.asFea)NN)ry)r}r~rrrvrirKrKrKrNrs c@s,eZdZdZd ddZddZd dd ZdS) rz&A ``GDEF`` table ``Attach`` statement.NcCstj||||_||_dS)N)rBrvr contourPoints)rurrrtrKrKrNrvs zAttachStatement.__init__cCs |jj}|j|j||jdS)z3Calls the builder's ``add_attach_points`` callback.N)rrZadd_attach_pointsrtr)rurwrrKrKrNrxs zAttachStatement.buildrycCs$dj|jjdjdd|jDS)Nz Attach {} {};rcss|]}t|VqdS)N)str)rLcrKrKrNrOsz(AttachStatement.asFea..)rrrirPr)rur{rKrKrNriszAttachStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrs c@s,eZdZdZd ddZddZd dd ZdS) 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.Nc Cs~tj||||||_|_|_t||_xLt|D]@\}}|r6ydd|DWq6tk rt|g|j|<Yq6Xq6WdS)Ncss|] }|VqdS)NrK)rL_rKrKrNrOsz4ChainContextPosStatement.__init__..) rBrvrrrrlookupsrU TypeError)rurrrrrtir[rKrKrNrvs  z!ChainContextPosStatement.__init__cCsJdd|jD}dd|jD}dd|jD}|j|j||||jdS)z7Calls the builder's ``add_chain_context_pos`` callback.cSsg|] }|jqSrK)r)rLrrKrKrNrsz2ChainContextPosStatement.build..cSsg|] }|jqSrK)r)rLrsrKrKrNrscSsg|] }|jqSrK)r)rLrrKrKrNrsN)rrradd_chain_context_posrtr)rurwrrrrKrKrNrxs zChainContextPosStatement.buildrycCs d}t|js,t|js,tdd|jDrt|jrT|djdd|jDd7}xlt|jD]^\}}||jd7}|j|rx |j|D]}|d|j 7}qW|t|jd kr`|d7}q`Wt|jr|ddjt t|j7}n|djt t|j 7}|d 7}|S) Nzpos cSsg|] }|dk qS)NrK)rLrrKrKrNrsz2ChainContextPosStatement.asFea..rcss|]}|jVqdS)N)ri)rLrsrKrKrNrOsz1ChainContextPosStatement.asFea..rz lookup rkr) rprranyrrPrUrrirhrr)rur{rrrslurKrKrNris$      zChainContextPosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr!s   c@s,eZdZdZd ddZddZd dd ZdS) 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.Nc Cs~tj||||||_|_|_t||_xLt|D]@\}}|r6ydd|DWq6tk rt|g|j|<Yq6Xq6WdS)Ncss|] }|VqdS)NrK)rLrrKrKrNrO sz6ChainContextSubstStatement.__init__..) rBrvrrrrrrUr)rurrrrrtrr[rKrKrNrvs  z#ChainContextSubstStatement.__init__cCsJdd|jD}dd|jD}dd|jD}|j|j||||jdS)z9Calls the builder's ``add_chain_context_subst`` callback.cSsg|] }|jqSrK)r)rLrrKrKrNrsz4ChainContextSubstStatement.build..cSsg|] }|jqSrK)r)rLrsrKrKrNrscSsg|] }|jqSrK)r)rLrrKrKrNrsN)rrradd_chain_context_substrtr)rurwrrrrKrKrNrxs z ChainContextSubstStatement.buildrycCs d}t|js,t|js,tdd|jDrt|jrT|djdd|jDd7}xlt|jD]^\}}||jd7}|j|rx |j|D]}|d|j 7}qW|t|jd kr`|d7}q`Wt|jr|ddjt t|j7}n|djt t|j 7}|d 7}|S) Nzsub cSsg|] }|dk qS)NrK)rLrrKrKrNrsz4ChainContextSubstStatement.asFea..rcss|]}|jVqdS)N)ri)rLrsrKrKrNrO"sz3ChainContextSubstStatement.asFea..rz lookup rkr) rprrrrrPrUrrirhrr)rur{rrrsrrKrKrNris$      z ChainContextSubstStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr"s   c@s,eZdZdZd ddZddZd dd ZdS) r$znA cursive positioning statement. Entry and exit anchors can either be :class:`Anchor` objects or ``None``.NcCs$tj||||_|||_|_dS)N)rBrvr entryAnchor exitAnchor)rurrrrtrKrKrNrv6s zCursivePosStatement.__init__cCs |j|j|jj|j|jdS)z8Calls the builder object's ``add_cursive_pos`` callback.N)Zadd_cursive_posrtrrrr)rurwrKrKrNrx;szCursivePosStatement.buildrycCs<|jr|jjnd}|jr$|jjnd}dj|jj||S)Nz zpos cursive {} {} {};)rrirrr)rur{entryexitrKrKrNriAszCursivePosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr$2s c@s,eZdZdZd ddZddZd dd ZdS) r)zExample: ``feature salt;``NcCstj|||||_|_dS)N)rBrvrt featureName)rurrtrKrKrNrvJs z"FeatureReferenceStatement.__init__cCs|j|j|jdS)z>Calls the builder object's ``add_feature_reference`` callback.N)Zadd_feature_referencertr)rurwrKrKrNrxNszFeatureReferenceStatement.buildrycCs dj|jS)Nz feature {};)rr)rur{rKrKrNriRszFeatureReferenceStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr)Gs c@s,eZdZdZd ddZddZd dd ZdS) 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`_ .NcCstj||||_dS)N)rBrv chainContexts)rurrtrKrKrNrv]s zIgnorePosStatement.__init__cCsXxR|jD]H\}}}dd|D}dd|D}dd|D}|j|j|||gqWdS)z[Calls the builder object's ``add_chain_context_pos`` callback on each rule context.cSsg|] }|jqSrK)r)rLrrKrKrNresz,IgnorePosStatement.build..cSsg|] }|jqSrK)r)rLrsrKrKrNrfscSsg|] }|jqSrK)r)rLrrKrKrNrgsN)rrrt)rurwrrrrKrKrNrxas zIgnorePosStatement.buildrycCsg}x|jD]\}}}d}t|s*t|rt|rJ|djtt|d7}|djdd|D7}t|r|ddjtt|7}n|djtt|7}|j|q Wddj|dS)Nryrcss|]}|jdVqdS)rN)ri)rLrsrKrKrNrOqsz+IgnorePosStatement.asFea..z ignore pos z, r)rrprPrrir)rur{contextsrrrrrKrKrNrijszIgnorePosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr,Vs  c@s,eZdZdZd ddZddZd dd ZdS) r-zAn ``ignore sub`` 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`_ .NcCstj||||_dS)N)rBrvr)rurrtrKrKrNrvs zIgnoreSubstStatement.__init__cCsXxR|jD]H\}}}dd|D}dd|D}dd|D}|j|j|||gqWdS)z]Calls the builder object's ``add_chain_context_subst`` callback on each rule context.cSsg|] }|jqSrK)r)rLrrKrKrNrsz.IgnoreSubstStatement.build..cSsg|] }|jqSrK)r)rLrsrKrKrNrscSsg|] }|jqSrK)r)rLrrKrKrNrsN)rrrt)rurwrrrrKrKrNrxs zIgnoreSubstStatement.buildrycCsg}x|jD]\}}}d}t|s*t|rt|rJ|djtt|d7}|djdd|D7}t|r|ddjtt|7}n|djtt|7}|j|q Wddj|dS)Nryrcss|]}|jdVqdS)rN)ri)rLrsrKrKrNrOsz-IgnoreSubstStatement.asFea..z ignore sub z, r)rrprPrrir)rur{rrrrrrKrKrNriszIgnoreSubstStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr-zs  cs4eZdZdZd fdd ZddZd dd ZZS) r.zAn ``include()`` statement.Ncstt|j|||_dS)N)rr.rvfilename)rurrt)rrKrNrvszIncludeStatement.__init__cCstd|jdS)NzqBuilding an include statement is not implemented yet. Instead, use Parser(..., followIncludes=True) for building.)rrt)rurKrKrNrxszIncludeStatement.buildrycCs|d|jS)Nz include(%s);)r)rur{rKrKrNriszIncludeStatement.asFea)N)ry)r}r~rrrvrxrirrKrK)rrNr.sc@s,eZdZdZd ddZddZd d d ZdS)r/z*A ``language`` statement within a feature.TFNcCs2tj||t|dkst||_||_||_dS)Nr )rBrvrprrZinclude_defaultra)rurZrrartrKrKrNrvs  zLanguageStatement.__init__cCs|j|j|j|j|jddS)z4Call the builder object's ``set_language`` callback.)rtrZrraN)Z set_languagertrZrra)rurwrKrKrNrxs zLanguageStatement.buildrycCs8dj|jj}|js|d7}|jr,|d7}|d7}|S)Nz language {}z exclude_dfltz requiredr)rrZrrra)rur{rrKrKrNriszLanguageStatement.asFea)TFN)ry)r}r~rrrvrxrirKrKrKrNr/s  c@s,eZdZdZd ddZddZd dd ZdS) r0z)A top-level ``languagesystem`` statement.NcCstj|||||_|_dS)N)rBrvrbrZ)rurbrZrtrKrKrNrvs z LanguageSystemStatement.__init__cCs|j|j|j|jdS)z.)rrrirPr)rur{rKrKrNrisz#LigatureCaretByIndexStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr1s c@s,eZdZdZd ddZddZd dd ZdS) r2zA ``GDEF`` table ``LigatureCaretByPos`` statement. ``glyphs`` should be a `glyph-containing object`_, and ``carets`` should be a list of integers.NcCstj|||||_|_dS)N)rBrvrr)rurrrtrKrKrNrvs z$LigatureCaretByPosStatement.__init__cCs$|jj}|j|j|t|jdS)z@Calls the builder object's ``add_ligatureCaretByPos_`` callback.N)rrZadd_ligatureCaretByPos_rtrr)rurwrrKrKrNrxs z!LigatureCaretByPosStatement.buildrycCs$dj|jjdjdd|jDS)NzLigatureCaretByPos {} {};rcss|]}t|VqdS)N)r)rLrrKrKrNrOsz4LigatureCaretByPosStatement.asFea..)rrrirPr)rur{rKrKrNri sz!LigatureCaretByPosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr2s c@s,eZdZdZd ddZddZd dd ZdS) 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.NcCs4tj||||||_|_|_|||_|_dS)N)rBrvrrrr forceChain)rurrrrrrtrKrKrNrvs zLigatureSubstStatement.__init__cCsNdd|jD}dd|jD}dd|jD}|j|j||||j|jdS)NcSsg|] }|jqSrK)r)rLrrKrKrNr"sz0LigatureSubstStatement.build..cSsg|] }|jqSrK)r)rLrsrKrKrNr#scSsg|] }|jqSrK)r)rLrrKrKrNr$s)rrrZadd_ligature_substrtrr)rurwrrrrKrKrNrx!s zLigatureSubstStatement.buildrycCsd}t|jst|js|jrt|jrF|djdd|jDd7}|djdd|jD7}t|jr|ddjdd|jD7}n|djdd|jD7}|d7}|t|j7}|d 7}|S) Nzsub rcss|]}|jVqdS)N)ri)rLrsrKrKrNrO-sz/LigatureSubstStatement.asFea..css|]}|jdVqdS)rN)ri)rLrsrKrKrNrO.scss|]}|jVqdS)N)ri)rLrsrKrKrNrO0scss|]}|jVqdS)N)ri)rLrsrKrKrNrO2sz by r)rprrrrPrrir)rur{rrKrKrNri)s   zLigatureSubstStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr3s c@s,eZdZdZd ddZddZd d d ZdS) 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.rNcCs"tj||||_||_||_dS)N)rBrvrmarkAttachmentmarkFilteringSet)rurrrrtrKrKrNrv?s zLookupFlagStatement.__init__cCsHd}|jdk r|jj}d}|jdk r0|jj}|j|j|j||dS)z8Calls the builder object's ``set_lookup_flag`` callback.N)rrrZset_lookup_flagrtr)rurwZ markAttachZ markFilterrKrKrNrxGs    zLookupFlagStatement.buildrycCsg}ddddg}d}x8tt|D](}|j|@dkrB|j|||d>}q"W|jdk rn|jdj|jj|jdk r|jdj|jj|sd g}d jd j|S) NZ RightToLeftZIgnoreBaseGlyphsZIgnoreLigaturesZ IgnoreMarksrkrzMarkAttachmentType {}zUseMarkFilteringSet {}0zlookupflag {};r) rangerprrrrrirrP)rur{rflagsrrrKrKrNriQs    zLookupFlagStatement.asFea)rNNN)ry)r}r~rrrvrxrirKrKrKrNr49s  c@s,eZdZdZd ddZddZd dd ZdS) r5zRepresents a ``lookup ...;`` statement to include a lookup in a feature. The ``lookup`` should be a :class:`LookupBlock` object.NcCstj|||||_|_dS)N)rBrvrtr[)rur[rtrKrKrNrvgs z!LookupReferenceStatement.__init__cCs|j|jjdS)z8Calls the builder object's ``add_lookup_call`` callback.N)Zadd_lookup_callr[rh)rurwrKrKrNrxkszLookupReferenceStatement.buildrycCsdj|jjS)Nz lookup {};)rr[rh)rur{rKrKrNrioszLookupReferenceStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr5bs c@s,eZdZdZd ddZddZd dd ZdS) 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.NcCstj|||||_|_dS)N)rBrvrfmarks)rurfrrtrKrKrNrvxs zMarkBasePosStatement.__init__cCs|j|j|jj|jdS)z:Calls the builder object's ``add_mark_base_pos`` callback.N)Zadd_mark_base_posrtrfrr)rurwrKrKrNrx|szMarkBasePosStatement.buildrycCsRdj|jj}x4|jD]*\}}|d|tdj|j|j7}qW|d7}|S)Nz pos base {}rz {} mark @{}r)rrfrirrrh)rur{ramrKrKrNris &zMarkBasePosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr6ss c@s,eZdZdZd ddZddZd dd ZdS) 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; NcCstj|||||_|_dS)N)rBrv ligaturesr)rurrrtrKrKrNrvs zMarkLigPosStatement.__init__cCs|j|j|jj|jdS)z9Calls the builder object's ``add_mark_lig_pos`` callback.N)Zadd_mark_lig_posrtrrr)rurwrKrKrNrxszMarkLigPosStatement.buildrycCsdj|jj}g}x||jD]r}d}|dks6t| rLd|tdd}n8x6|D].\}}|d|tddj|j|j7}qRW|j|qW|d|tdj|7}|d7}|S) Nzpos ligature {}ryrrjz z {} mark @{}Z ligComponentr) rrrirrprrhrrP)rur{rZligsltemprrrKrKrNris (zMarkLigPosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr7s c@s,eZdZdZd ddZddZd dd ZdS) r8zA mark-to-mark positioning rule. The ``baseMarks`` must be a `glyph-containing object`_. The ``marks`` should be a list of (:class:`Anchor`, :class:`MarkClass`) tuples.NcCstj|||||_|_dS)N)rBrv baseMarksr)rurrrtrKrKrNrvs zMarkMarkPosStatement.__init__cCs|j|j|jj|jdS)z:Calls the builder object's ``add_mark_mark_pos`` callback.N)Zadd_mark_mark_posrtrrr)rurwrKrKrNrxszMarkMarkPosStatement.buildrycCsRdj|jj}x4|jD]*\}}|d|tdj|j|j7}qW|d7}|S)Nz pos mark {}rz {} mark @{}r)rrrirrrh)rur{rrrrKrKrNris &zMarkMarkPosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr8s c@s,eZdZdZd ddZddZd d d ZdS) 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. FNcCs2tj||||||_|_|_||_||_dS)N)rBrvrrrrr)rurrrrrrtrKrKrNrvs zMultipleSubstStatement.__init__cCsdd|jD}dd|jD}|j rdt|jdrdxJ|jjD]}|j|j||||j|jq@Wn|j|j||j||j|jdS)z;Calls the builder object's ``add_multiple_subst`` callback.cSsg|] }|jqSrK)r)rLrrKrKrNrsz0MultipleSubstStatement.build..cSsg|] }|jqSrK)r)rLrrKrKrNrsrN) rrrrmrrZadd_multiple_substrtr)rurwrrrrKrKrNrxszMultipleSubstStatement.buildrycCsd}t|jst|js|jrzt|jrB|djtt|jd7}|t|jd7}t|jr|ddjtt|j7}n|t|j7}|jpt g}|d7}|djtt|7}|d7}|S)Nzsub rrz by r) rprrrrPrrirrr)rur{rrrKrKrNris  zMultipleSubstStatement.asFea)FN)ry)r}r~rrrvrxrirKrKrKrNr9s  c@s,eZdZdZd ddZddZd d d ZdS) 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 `_. FNcCs2tj||||_|||_|_|||_|_dS)N)rBrv enumeratedglyphs1 valuerecord1glyphs2 valuerecord2)rurrrrrrtrKrKrNrvs zPairPosStatement.__init__cCs|jrN|jj|jjg}x.tj|D] \}}|j|j||j||j q&WdSt |jt odt |jt }|r|j|j|jj |j|jj |j n$|j |j|jj|j|jj|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``. N)rrrr itertoolsproductZadd_specific_pair_posrtrrrnr rZadd_class_pair_pos)rurwrsZglyph1Zglyph2Z is_specificrKrKrNrx s*   zPairPosStatement.buildrycCsj|jr dnd}|jrB|dj|jj|jj|jj|jj7}n$|dj|jj|jj|jj7}|S)Nzenum ryzpos {} {} {} {};z pos {} {} {};)rrrrrirr)rur{rrKrKrNriEszPairPosStatement.asFea)FN)ry)r}r~rrrvrxrirKrKrKrNr<s  %c@s,eZdZdZd ddZddZd dd ZdS) r=aPA reverse chaining substitution statement. You don't see those every day. Note the unusual argument order: ``suffix`` comes `before` ``glyphs``. ``old_prefix``, ``old_suffix``, ``glyphs`` and ``replacements`` should be lists of `glyph-containing objects`_. ``glyphs`` and ``replacements`` should be one-item lists. NcCs*tj|||||_|_||_||_dS)N)rBrv old_prefix old_suffixr replacements)rurrrrrtrKrKrNrv^s z)ReverseChainSingleSubstStatement.__init__cCstdd|jD}dd|jD}|jdj}|jdj}t|dkrT|t|}|j|j||tt ||dS)NcSsg|] }|jqSrK)r)rLrrKrKrNresz:ReverseChainSingleSubstStatement.build..cSsg|] }|jqSrK)r)rLrrKrKrNrfsrrk) rrrrrrpZadd_reverse_chain_single_substrtdictzip)rurwrr originalsreplacesrKrKrNrxds  z&ReverseChainSingleSubstStatement.buildrycCsd}t|jst|jrt|jr@|djdd|jDd7}|djdd|jD7}t|jr|ddjdd|jD7}n|djtt|j7}|djdjdd|jD7}|S) Nzrsub rcss|]}t|VqdS)N)ri)rLrsrKrKrNrOssz9ReverseChainSingleSubstStatement.asFea..css|]}t|dVqdS)rN)ri)rLrsrKrKrNrOtscss|]}t|VqdS)N)ri)rLrsrKrKrNrOvsz by {};css|]}t|VqdS)N)ri)rLrsrKrKrNrOys) rprrrPrrrirr)rur{rrKrKrNrios    z&ReverseChainSingleSubstStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr=Us  c@s,eZdZdZd ddZddZd dd ZdS) 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. NcCs0tj|||||_|_||_||_||_dS)N)rBrvrrrrr)rurreplacerrrrtrKrKrNrvs  zSingleSubstStatement.__init__cCsxdd|jD}dd|jD}|jdj}|jdj}t|dkrT|t|}|j|j||tt |||j dS)z9Calls the builder object's ``add_single_subst`` callback.cSsg|] }|jqSrK)r)rLrrKrKrNrsz.SingleSubstStatement.build..cSsg|] }|jqSrK)r)rLrrKrKrNrsrrkN) rrrrrrpZadd_single_substrtrrr)rurwrrrrrKrKrNrxs   zSingleSubstStatement.buildrycCsd}t|jst|js|jrt|jrF|djdd|jDd7}|djdd|jD7}t|jr|ddjdd|jD7}n|djdd|jD7}|djdjd d|jD7}|S) Nzsub rcss|]}t|VqdS)N)ri)rLrsrKrKrNrOsz-SingleSubstStatement.asFea..css|]}t|dVqdS)rN)ri)rLrsrKrKrNrOscss|]}t|VqdS)N)ri)rLrsrKrKrNrOscss|]}t|VqdS)N)ri)rLrsrKrKrNrOsz by {};css|]}t|VqdS)N)ri)rLrsrKrKrNrOs)rprrrrPrrr)rur{rrKrKrNris    zSingleSubstStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr@}s c@s,eZdZdZd ddZddZd dd ZdS) r>zA ``script`` statement.NcCstj||||_dS)N)rBrvrb)rurbrtrKrKrNrvs zScriptStatement.__init__cCs|j|j|jdS)z,Calls the builder's ``set_script`` callback.N)Z set_scriptrtrb)rurwrKrKrNrxszScriptStatement.buildrycCsdj|jjS)Nz script {};)rrbr)rur{rKrKrNriszScriptStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr>s c@s,eZdZdZd ddZddZd dd ZdS) 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.NcCs,tj||||||_|_|_||_dS)N)rBrvr_rrr)rur_rrrrtrKrKrNrvs zSinglePosStatement.__init__cCsJdd|jD}dd|jD}dd|jD}|j|j||||jdS)z7Calls the builder object's ``add_single_pos`` callback.cSsg|] }|jqSrK)r)rLrrKrKrNrsz,SinglePosStatement.build..cSsg|] }|jqSrK)r)rLrrKrKrNrscSsg|]\}}|j|fqSrK)r)rLrsrrKrKrNrsN)rrr_Zadd_single_posrtr)rurwrrr_rKrKrNrxszSinglePosStatement.buildrycCsd}t|jst|js|jrt|jrB|djtt|jd7}|djdd|jD7}t|jr|ddjtt|j7}n|djdd|jD7}|d7}|S)Nzpos rcSs8g|]0}t|dd|dr.d|djndqS)rrrkrry)ri)rLrrKrKrNrsz,SinglePosStatement.asFea..cSs4g|],}t|dd|dr*|djndqS)rrrkry)ri)rLrrKrKrNrsr)rprrrrPrrir_)rur{rrKrKrNris  zSinglePosStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr?s c@s,eZdZdZd ddZddZd dd ZdS) rFzRepresents a subtable break.NcCstj||dS)N)rBrv)rurtrKrKrNrvszSubtableStatement.__init__cCs|j|jdS)zrz <%s %s %s %s>z<%s %s %s %s %s %s %s %s>) rrrrrrrrrrrR) rur{rrrrrrrrrrKrKrNri s< zValueRecord.asFeac stfddd DS) Nc3s|]}t|dk VqdS)N)getattr)rLv)rurKrNrONsz'ValueRecord.__bool__..rrrrrrrr)rrrrrrrr)r)rurK)rurN__bool__Ls zValueRecord.__bool__) NNNNNNNNFN)ry) r}r~rrrvrrrrir __nonzero__rKrKrKrNrHs"   ,c@s$eZdZdZdddZd ddZdS) rIz+Represents a named value record definition.NcCstj||||_||_dS)N)rBrvrhr)rurhrrtrKrKrNrvas zValueRecordDefinition.__init__rycCsdj|jj|jS)NzvalueRecordDef {} {};)rrrirh)rur{rKrKrNrifszValueRecordDefinition.asFea)N)ry)r}r~rrrvrirKrKrKrNrI^s cCsJ|dkr|dkr|dkrdS|dkr8|dkr8|dkr8dSdj|||SdS)Nrki ryr1z{} {} {})r)pidZeidZlidrKrKrNsimplify_name_attributesjs r c@s,eZdZdZd ddZddZd dd ZdS) r:zRepresents a name record. (`Section 9.e. `_)NcCs.tj||||_||_||_||_||_dS)N)rBrvnameID platformID platEncIDlangIDstring)rur r r rrrtrKrKrNrvvs  zNameRecord.__init__cCs$|j|j|j|j|j|j|jdS)z8Calls the builder object's ``add_name_record`` callback.N)Zadd_name_recordrtr r r rr)rurwrKrKrNrx~szNameRecord.buildrycsddt|j|j|j}|dkr.td|jt|j|d|dkrldjfddt d t d D}ndjfd dD}t |j|j|j}|dkr|d 7}d j |j ||S)NcSs,|dkr |dkr |dkr t|S||SdS)N ~"\)rr)chr)rZescape_patternrKrKrNescapesz NameRecord.asFea..escapezUnsupported encoding)encoding utf_16_berycs2g|]*}t|dt|ddqS)rkz\%04x)r)rLr)rrrKrNrsz$NameRecord.asFea..rrjcsg|]}t|dqS)z\%02x)r)rLb)rrKrNrsrznameid {} {}"{}";)rr r rrrtrrrPrrpr rr )rur{rZescaped_stringplatrK)rrrNris  zNameRecord.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr:ss  c@s"eZdZdZddZdddZdS) r(z4Represents a ``sizemenuname`` or ``name`` statement.cCstj|||j|jdS)z8Calls the builder object's ``add_featureName`` callback.N)r:rxZadd_featureNamer )rurwrKrKrNrxs zFeatureNameStatement.buildrycCsF|jdkrd}nd}t|j|j|j}|dkr6|d7}dj|||jS)NsizeZ sizemenunamerhryrz {} {}"{}";)r r r r rrr)rur{rrrKrKrNris zFeatureNameStatement.asFeaN)ry)r}r~rrrxrirKrKrKrNr(sc@seZdZdZdddZdS)rEz+Represents a STAT table ``name`` statement.rycCs0t|j|j|j}|dkr"|d7}dj||jS)Nryrz name {}"{}";)r r r rrr)rur{rrKrKrNriszSTATNameStatement.asFeaN)ry)r}r~rrrirKrKrKrNrEsc@s,eZdZdZd ddZddZd dd ZdS) rAzA ``parameters`` statement.NcCs(tj||||_||_||_||_dS)N)rBrv DesignSize SubfamilyID RangeStartRangeEnd)rurrrrrtrKrKrNrvs  zSizeParameters.__init__cCs |j|j|j|j|j|jdS)z|jr dnd}dd|jD}dj|dj|j||dj|S)NZVertZHorizc Ss2g|]*}dj|d|ddjtt|dqS)z{} {} {}rrkrrj)rrPrr)rLrrKrKrNrsz"BaseAxis.asFea..z2{}Axis.BaseTagList {}; {}{}Axis.BaseScriptList {};rz, )rr&rrPr%)rur{ directionr&rKrKrNris  zBaseAxis.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr s c@s,eZdZdZd ddZddZd dd ZdS) 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.NcCstj||||_||_dS)N)rBrvrr)rurrrtrKrKrNrv*s zOS2Field.__init__cCs|j|j|jdS)z6Calls the builder object's ``add_os2_field`` callback.N)Z add_os2_fieldrr)rurwrKrKrNrx/szOS2Field.buildryc sddd}d}tdd|D}|jfdd|Ddg|d<dddg|d<|j|krdj||jd||jd|jSdS) NcSsdjtt|S)Nr)rPrr)rrKrKrN intarr2str4sz"OS2Field.asFea..intarr2strFSType TypoAscender TypoDescender TypoLineGap winAscent winDescentXHeight CapHeight WeightClass WidthClass LowerOpSize UpperOpSize UnicodeRange CodePageRangecSsg|]}|j|tgfqSrK)rqr)rLrrKrKrNrFsz"OS2Field.asFea..csg|]}|j|gfqSrK)rq)rLr)r(rKrNrGsZPanoseZpanoseZVendorcSs dj|S)Nz"{}")r)rrKrKrNIsz OS2Field.asFea..vendorz{} {};rrkry) r)r*r+r,r-r.r/r0r1r2r3r4)r5r6)rupdaterrr)rur{numbersrangeskeywordsrK)r(rNri3s,  "zOS2Field.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr;%s c@s,eZdZdZd ddZddZd dd ZdS) r+zAn entry in the ``hhea`` table.NcCstj||||_||_dS)N)rBrvrr)rurrrtrKrKrNrvTs zHheaField.__init__cCs|j|j|jdS)z7Calls the builder object's ``add_hhea_field`` callback.N)Zadd_hhea_fieldrr)rurwrKrKrNrxYszHheaField.buildrycCs*d}tdd|D}dj||j|jS) N CaretOffsetAscender DescenderLineGapcSsg|]}|j|fqSrK)rq)rLrrKrKrNr_sz#HheaField.asFea..z{} {};)r=r>r?r@)rrrr)rur{fieldsr<rKrKrNri]szHheaField.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr+Qs c@s,eZdZdZd ddZddZd dd ZdS) rJzAn entry in the ``vhea`` table.NcCstj||||_||_dS)N)rBrvrr)rurrrtrKrKrNrvfs zVheaField.__init__cCs|j|j|jdS)z7Calls the builder object's ``add_vhea_field`` callback.N)Zadd_vhea_fieldrr)rurwrKrKrNrxkszVheaField.buildrycCs*d}tdd|D}dj||j|jS)NVertTypoAscenderVertTypoDescenderVertTypoLineGapcSsg|]}|j|fqSrK)rq)rLrrKrKrNrqsz#VheaField.asFea..z{} {};)rBrCrD)rrrr)rur{rAr<rKrKrNrioszVheaField.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrJcs c@s,eZdZdZd ddZddZd dd ZdS) 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 NcCs(tj||||_||_||_||_dS)N)rBrvr axisOrdernamesrt)rurrErFrtrKrKrNrv~s  z STATDesignAxisStatement.__init__cCs|j||jdS)N)Z addDesignAxisrt)rurwrKrKrNrxszSTATDesignAxisStatement.buildrycsPt7d|jd|jd}|djfdd|jDd7}|d7}|S)Nz DesignAxis rz { rcsg|]}|jdqS))r{)ri)rLr)r{rKrNrsz1STATDesignAxisStatement.asFea..z};)rrrErPrF)rur{rrK)r{rNris &zSTATDesignAxisStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrDus c@s,eZdZdZd ddZddZd dd ZdS) r%ziSTAT table ElidedFallbackName Args: names: a list of :class:`STATNameStatement` objects NcCstj||||_||_dS)N)rBrvrFrt)rurFrtrKrKrNrvs zElidedFallbackName.__init__cCs|j|j|jdS)N)setElidedFallbackNamerFrt)rurwrKrKrNrxszElidedFallbackName.buildrycs>t7d}|djfdd|jDd7}|d7}|S)NzElidedFallbackName { rcsg|]}|jdqS))r{)ri)rLr)r{rKrNrsz,ElidedFallbackName.asFea..z};)rrPrF)rur{rrK)r{rNris &zElidedFallbackName.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr%s c@s,eZdZdZd ddZddZd dd ZdS) r&zpSTAT table ElidedFallbackNameID Args: value: an int pointing to an existing name table name ID NcCstj||||_||_dS)N)rBrvrrt)rurrtrKrKrNrvs zElidedFallbackNameID.__init__cCs|j|j|jdS)N)rGrrt)rurwrKrKrNrxszElidedFallbackNameID.buildrycCsd|jdS)NzElidedFallbackNameID r)r)rur{rKrKrNriszElidedFallbackNameID.asFea)N)ry)r}r~rrrvrxrirKrKrKrNr&s c@s,eZdZdZd ddZddZd dd ZdS) 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 NcCs"tj||||_||_||_dS)N)rBrvrF locationsr)rurFrHrrtrKrKrNrvs zSTATAxisValueStatement.__init__cCs|j||jdS)N)ZaddAxisValueRecordrt)rurwrKrKrNrxszSTATAxisValueStatement.buildryc Csd}x|jD]}||j7}q Wx"|jD]}||j7}|d7}q(W|jrddg}g}d}x8tt|D](}|j|@dkr|j|||d>}qhW|ddj|d 7}|d 7}|S) Nz AxisValue { rZOlderSiblingFontAttributeZElidableAxisValueNamerkrzflag rz; z};)rHrirFrrrprrP) rur{rrtZ nameRecordrZ flagStringsrrrKrKrNris"     zSTATAxisValueStatement.asFea)N)ry)r}r~rrrvrxrirKrKrKrNrCs c@s$eZdZdZdddZd ddZdS) rz A STAT table Axis Value Location Args: tag (str): a 4 letter axis tag values (list): a list of ints and/or floats NcCstj||||_||_dS)N)rBrvrvalues)rurrIrtrKrKrNrvs z#AxisValueLocationStatement.__init__rycCs6|d|jd7}|djdd|jDd7}|S)Nz location rcss|]}t|VqdS)N)r)rLrrKrKrNrOsz3AxisValueLocationStatement.asFea..z; )rrPrI)rurrKrKrNris z AxisValueLocationStatement.asFea)N)ry)r}r~rrrvrirKrKrKrNrs z )VZfontTools.feaLib.errorrZfontTools.feaLib.locationrZfontTools.misc.encodingToolsrZfontTools.misc.textToolsrr collectionsrrr__all__rRrrrriobjectr rBr'r rr rrrrrr rrrrGrrrrrrrrr!r"r$r)r,r-r.r/r0r*r1r2r3r4r5r6r7r8r9r<r=r@r>r?rFrHrIr r:r(rErAr r#rr;r+rJrDr%r&rCrrKrKrKrNs      >  -'%%::$$')83M(.(n  1 ,(