
     i&                      d dl mZ d dlmZ d dlmZmZmZmZ d dl	m
Z
 d dlmZmZmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZmZ d dlmZm Z  d dl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 d dl2m3Z3 d dl4m5Z5 d dl6m7Z7 d dl8m9Z9 d dl:m;Z; d dl<m=Z=m>Z> d dl?m@Z@ d dlAZAd dlBZBd dlCmDZD d dlEZEd dlFZFd dlGZG eEjH        eI          ZJddZK	 ddZL G d deM          ZNdS )    )annotations)sstruct)Tagtostr
binary2numsafeEval)FeatureLibError)LookupDebugInfoLOOKUP_DEBUG_INFO_KEYLOOKUP_DEBUG_ENV_VAR)Parser)FeatureFile)VariableScalarVariableScalarBuilder)builder)
maxCtxFont)newTablegetTableModule)otBaseotTables)AlternateSubstBuilderChainContextPosBuilderChainContextSubstBuilderLigatureSubstBuilderMultipleSubstBuilderCursivePosBuilderMarkBasePosBuilderMarkLigPosBuilderMarkMarkPosBuilderReverseChainSingleSubstBuilderSingleSubstBuilderClassPairPosSubtableBuilderPairPosBuilderSinglePosBuilderChainContextualRuleAnySubstBuilder)OpenTypeLibError)VarLibError)OnlineVarStoreBuilder)buildVarDevTable)addFeatureVariationsRaw)normalizeValuepiecewiseLinearMap)defaultdictN)StringIOFc                T    t          | |          }|                    ||           dS )a  Add features from a file to a font. Note that this replaces any features
    currently present.

    Args:
        font (feaLib.ttLib.TTFont): The font object.
        featurefile: Either a path or file object (in which case we
            parse it into an AST), or a pre-parsed AST instance.
        tables: If passed, restrict the set of affected tables to those in the
            list.
        debug: Whether to add source debugging information to the font in the
            ``Debg`` table

    tablesdebugN)Builderbuild)fontfeaturefiler2   r3   r   s        b/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/fontTools/feaLib/builder.pyaddOpenTypeFeaturesr9   6   s/     dK((GMMuM-----    c                v    t          t          |                    }|r||_        t          | |||           dS )ae  Add features from a string to a font. Note that this replaces any
    features currently present.

    Args:
        font (feaLib.ttLib.TTFont): The font object.
        features: A string containing feature code.
        filename: The directory containing ``filename`` is used as the root of
            relative ``include()`` paths; if ``None`` is provided, the current
            directory is assumed.
        tables: If passed, restrict the set of affected tables to those in the
            list.
        debug: Whether to add source debugging information to the font in the
            ``Debg`` table

    r1   N)r/   r   namer9   )r6   featuresfilenamer2   r3   r7   s         r8   addOpenTypeFeaturesFromStringr?   H   sD    & 5??++K $#k&FFFFFFr:   c                     e Zd Z ed dD                       Zd ZdcdZd Zd Zddd	Z	d
 Z
d Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd  Z d! Z!d" Z"d# Z#d$ Z$d% Z%ded&Z&d' Z'ded(Z(d) Z)d* Z*d+ Z+d, Z,d- Z-d. Z.d/ Z/d0 Z0d1 Z1d2 Z2d3 Z3d4 Z4d5 Z5d6 Z6d7 Z7g fd8Z8d9 Z9d: Z:d; Z;	 ded<Z<d= Z=d> Z>e?d?             Z@d@ ZAdA ZBdB ZCdC ZDdD ZEdE ZFdF ZGdG ZHdH ZIdI ZJdJ ZKdK ZLdL ZMdM ZNdN ZOdO ZPdP ZQdQ ZRdR ZSdS ZTdT ZUdU ZVdV ZWdW ZXdX ZYdY ZZdfd^Z[d_ Z\d` Z]da e^j_        D             Z`db ZadS )gr4   c              #  4   K   | ]}t          |          V  d S N)r   ).0tags     r8   	<genexpr>zBuilder.<genexpr>b   s<           	C           r:   )
BASEGDEFGPOSGSUBOS/2headhhear<   vheaSTATc                D   || _         t          |t                    r|d c| _        | _        nd |c| _        | _        |                                | _        d | _        d|v rN|d         j        | _        t          d | j        D                       | _        t          j        |          | _        t                      | _        d | _        d| _        d | _        d| _        t                      | _        d| _        i | _        d | _        d | _        d | _        g | _        i i d| _        i | _        i | _        i | _        g | _        d | _        i | _         d| _!        t                      | _"        i | _#        t                      | _$        i | _%        i | _&        tO          tP                    | _)        d | _*        d | _+        g | _,        d | _-        d | _.        i | _/        i | _0        i | _1        i | _2        i | _3        i | _4        i | _5        i | _6        i | _7        i | _8        i | _9        i | _:        d S )Nfvarc                    g | ]	}|j         
S  )axisTag)rC   axs     r8   
<listcomp>z$Builder.__init__.<locals>.<listcomp>   s    000000r:   r   F)rI   rH   );r6   
isinstancer   	parseTreefilegetReverseGlyphMapglyphMapvarstorebuilderaxesr)   r   from_ttfscalar_buildersetdefault_language_systems_script_lookupflag_lookupflag_markFilterSet_use_extension_language_systemsseen_non_DFLT_script_named_lookups_cur_lookup_cur_lookup_name_cur_feature_name_lookups_lookup_locations	features_required_features_feature_variations_aalt_features_aalt_location_aalt_alternates_aalt_use_extension_featureNames_featureNames_ids_cv_parameters_cv_parameters_ids_cv_num_named_params_r.   listcv_characters_size_parameters_fontRevision_names_base_horiz_axis_base_vert_axis_attachPoints_ligCaretCoords_ligCaretPoints_glyphClassDefs_markAttach_markAttachClassID_markFilterSets_os2_hhea_vhea_stat_conditionsets_)selfr6   r7   s      r8   __init__zBuilder.__init__r   s!   	 k;// 	:(3T%DNDII(,k%DNDI//11#T>>V)DI#800di000$ $D  #8"@"F"FD),&)-&# #%*"  $!%)+R 8 8"$#%  " "#(  UU!#!ee"$$&!)$// $! $#!!!"$!	


 r:   NFc                     j         1t           j         j                                                   _          j                                         | j        }nPt          |          }| j        z
  }|r5d                    t          |                    }t          d| d          d|v r                                  d|v r                                  d|v r                                  d|v r                                  d|v r                                  d	|v r                                  d
|v r                                  dD ]}||vr                     |          } j        r                     ||           |j        j        dk    s |j        j        dk    s|j        j        dk    r!t7          |          x} j        |<   ||_        | j        v r j        |= t=           fddD                       r-d	 j        v r$t?           j                   j        d	         _         d|v r2 !                                }|r| j        d<   nd j        v r j        d= d|v r2 "                                }	|	r|	 j        d<   nd j        v r j        d= |s$tF          j$        %                    tL                    r '                                 d S d S )N, z9The following tables were requested but are unsupported: .rI   rK   rL   rM   r<   rJ   rN   rH   rI   r   c              3  *   K   | ]}|j         v V  d S rB   )r6   )rC   rD   r   s     r8   rE   z Builder.build.<locals>.<genexpr>   s*      <<Csdi<<<<<<r:   rG   rF   )(rW   r   rX   rZ   parser5   supportedTables	frozensetjoinsortedNotImplementedErrorbuild_feature_aalt_
build_head
build_hhea
build_vhea
build_name
build_OS_2
build_STAT	makeTablero   makeFeatureVariations
ScriptListScriptCountFeatureListFeatureCount
LookupListLookupCountr   r6   tableanyr   usMaxContext	buildGDEF	buildBASEosenvirongetr   	buildDebg)
r   r2   r3   unsupportedunsupported_stringrD   r   	fontTablegdefbases
   `         r8   r5   zBuilder.build   sI   >!#DIt}==CCEEDNT""">)FFv&&F 4#77K %)YYvk/B/B%C%C")-)- - -   V$$&&&VOOVOOVOOVOOVOOVOO# 	# 	#C&  NN3''E' 7**5#666 ,q00$1A55#/!33-5c]]:	DIcN"'		!!IcN<<<<+;<<<<< 	C49ATAT-7	-B-BDIf*V>>##D &$(	&!!49$$If%V>>##D &$(	&!!49$$If% 	BJNN#788 	NN	 	r:   c                     || j         |          }| j        |_        | j        |_        | j        |_        | j                            |           |S rB   )	r6   rb   
lookupflagrc   markFilterSetrd   	extensionrk   append)r   locationbuilder_classresults       r8   get_chained_lookup_zBuilder.get_chained_lookup_   sQ    ty(33 ,#=.V$$$r:   c                    | j         D ]8\  }}|||f}| j                            |g                               |           9d S rB   )re   rm   
setdefaultr   )r   lookupfeature_namescriptlangkeys         r8   add_lookup_to_feature_zBuilder.add_lookup_to_feature_  sW     1 	> 	>LFD4.CN%%c2..55f====	> 	>r:   c                t   | j         rct          | j                   |k    rK| j         j        | j        k    r6| j         j        | j        k    r!| j                             |          r| j         S | j        r| j         rt          d|           || j	        |          | _         | j        | j         _        | j        | j         _        | j
        | j         _        | j                            | j                    | j        r| j         | j        | j        <   | j        r |                     | j         | j                   | j         S )NOWithin a named lookup block, all rules must be of the same lookup type and flag)rh   typer   rb   r   rc   can_add_mappingri   r	   r6   rd   r   rk   r   rg   rj   r   )r   r   r   mappings       r8   get_lookup_zBuilder.get_lookup_  sL   	$T%&&-77 +t/??? .$2PPP 0099 Q ##  	T%5 	!0  
 )=H==&*&6#)-)G&%)%8"T-...  	J9=9ID 56! 	R ''(8$:PQQQr:   c           	     ^   | j         s	| j        sd S d | j                                        D             }| j         dgz   D ]\  }fd| j                                        D             }|s!dk    rt	          j        |dd           M|D ]\  }}}}|D ]}t          |t                    s|g}|D ]e}|                                                                D ]<\  }	}
|	                    |	g           
                    fd|
D                        =fd |                                D             }d	 |                                D             }|s|sd S d
 | j                                        D             | _        | j        }g | _        |                     | j        d| j                   |r"|                     |t                     }||_        |r"|                     |t$                    }||_        |                                  | j        
                    |           d S )Nc                4    i | ]\  }}|t          |          S rR   )ry   )rC   gas      r8   
<dictcomp>z/Builder.build_feature_aalt_.<locals>.<dictcomp>*  s$    KKKTQaaKKKr:   )Naaltc                6    g | ]\  \  }}}}|k    ||||fS rR   rR   )rC   r   r   featurelookupsr<   s        r8   rU   z/Builder.build_feature_aalt_.<locals>.<listcomp>,  s>       4+VT7Wd?? w0"??r:   r   z
: Feature z has not been definedc              3  $   K   | ]
}|v|V  d S rB   rR   )rC   r   alts_for_glyphs     r8   rE   z.Builder.build_feature_aalt_.<locals>.<genexpr><  s6       2 2&'1N3J3J3J3J3J3J2 2r:   c                L    i | ]!\  }}t          |          d k    ||d         "S )   r   lenrC   glyphrepls      r8   r   z/Builder.build_feature_aalt_.<locals>.<dictcomp>?  s5     
 
 
*udCIIQRNNE47NNNr:   c                @    i | ]\  }}t          |          d k    ||S )r   r   r   s      r8   r   z/Builder.build_feature_aalt_.<locals>.<dictcomp>B  s*    TTTc$iiRSmmmmmr:   c                4    i | ]\  \  }}}}|d k    |||f|S )r   rR   )rC   r   r   r   r   s        r8   r   z/Builder.build_feature_aalt_.<locals>.<dictcomp>E  sA     
 
 
0'w&   T7#W   r:   )rp   rr   itemsrm   warningswarnrV   ry   getAlternateGlyphsr   extendrk   start_featurerq   rs   r   r!   r   r   
alternatesend_feature)r   r   r   r   r   r   r   
lookuplistr   r   altssinglemultiold_lookupssingle_lookupmulti_lookupr   r<   s                   @@r8   r   zBuilder.build_feature_aalt_#  s   " 	4+@ 	F
 LKT-B-H-H-J-JKKK
"1^4DD 	 	NHd   8<8L8L8N8N  G  tv~~xxxQUQUQUVWWW29 	 	.gw")  J%j$77 2&0\
",  +1+D+D+F+F+L+L+N+N  KE4-7-B-B5"-M-MN*11 2 2 2 2+/2 2 2    	
 
.8.>.>.@.@
 
 
 UT
0@0@0B0BTTT 	e 	F
 
48N4H4H4J4J
 
 

 m4.8PQQQ 	+ ,,X7IJJM$*M! 	,++H6KLLL&+L#[)))))r:   c                   | j         sd S | j                            d          }|sPt          d          x}| j        d<   |                    d| j                   d|_        d|_        dx|_        |_        | j         |_	        d S )NrK   s6                                                         g      ?i<_l   e )
r|   r6   r   r   	decompiletableVersionmagicNumbercreatedmodifiedfontRevisionr   r   s     r8   r   zBuilder.build_headV  s    ! 	F	f%% 	8(0(8(88EDIf%OOJ	222!$E *E-77EMEN!/r:   c                   | j         sd S | j                            d          }|s;t          d          x}| j        d<   |                    d| j                   d|_        d| j         v r| j         d         |_        d| j         v r| j         d         |_        d| j         v r| j         d         |_        d| j         v r| j         d         |_	        d S d S )NrL   $                                          caretoffsetascender	descenderlinegap)
r   r6   r   r   r   r   caretOffsetascentdescentlineGapr   s     r8   r   zBuilder.build_hheab  s    z 	F	f%% 	,(0(8(88EDIf%OOJ	222!+EDJ&& $
= 9E##:j1EL$*$$ J{3EM
"" Jy1EMMM #"r:   c                l   | j         sd S | j                            d          }|s;t          d          x}| j        d<   |                    d| j                   d|_        d| j         v r| j         d         |_        d| j         v r| j         d         |_        d| j         v r| j         d         |_        d S d S )NrM   r   i  verttypoascenderverttypodescenderverttypolinegap)	r   r6   r   r   r   r   r   r  r  r   s     r8   r   zBuilder.build_vheas  s    z 	F	f%% 	,(0(8(88EDIf%OOJ	222!+E++:&89EL$*,, J':;EM
** J'89EMMM +*r:   c                ^    d |j         D             }t          dd          D ]
}||vr|c S d S )Nc                    g | ]	}|j         
S rR   )nameID)rC   r<   s     r8   rU   z,Builder.get_user_name_id.<locals>.<listcomp>  s    77744;777r:      i  )namesrange)r   r   nameIDsuser_name_ids       r8   get_user_name_idzBuilder.get_user_name_id  sV    775;777!#u-- 	$ 	$L7**#### +	$ 	$r:   c                X   d}d }|dk    rYt          j                    }| j        \  |_        |_        |_        |_        || j        v r| j        |         |_        nOd|_        nF|| j	        v rA| j        sn4|| j        v sJ t          j
                    }d|_        | j        |         |_        n|| j        v rt          j                    }d|_        | j                            |df|          |_        | j                            |df|          |_        | j                            |df|          |_        | j                            |d          |_        | j                            |df|          |_        t1          | j        |                   |_        | j        |         |_        |S )N  sizer   FeatUILabelNameIDFeatUITooltipTextNameIDSampleTextNameIDParamUILabelNameID_0)r   FeatureParamsSizer{   
DesignSizeSubfamilyID
RangeStartRangeEndru   SubfamilyNameIDrt   FeatureParamsStylisticSetVersionUINameIDrv   FeatureParamsCharacterVariantsFormatrw   r   r  r  r  rx   NumNamedParametersFirstParamUILabelNameIDr   rz   	CharCount	Character)r   rD   
NO_NAME_IDparamss       r8   buildFeatureParamszBuilder.buildFeatureParams  s    
&==/11F %!"!d,,,)-)?)D&&)*&&D&&&) >d44444!;==!""&"8"=D'''<>>FFM'+'>'B'B)*J( (F$ .2-D-H-H/0*. .F* '+&=&A&A():' 'F# )-(A(E(Ec1(M(MF%-1-D-H-H,-z. .F*  #4#6s#;<<F#237Fr:   c                   | j         sd S | j                            d          }|s t          d          x}| j        d<   g |_        | j         D ]}|\  }}}}}t          |t                    s|}|| j        v rC|| j        vr,| 	                    |          | j        |<   | j        |         J | j        |         }nQ|d         | j
        v rB|| j        vr,| 	                    |          | j        |<   | j        |         J | j        |         }|                    |||||           |j                                         d S )Nr<   r   )r}   r6   r   r   r  rV   intrt   ru   r  rv   rw   setNamesort)	r   r   r<   r	  
platformID	platEncIDlangIDstringrD   s	            r8   r   zBuilder.build_name  su   { 	F	f%% 	(0(8(88EDIf%EKK 	I 	ID<@9FJ	66 fc** :$,,,$"8886:6K6KE6R6R.s3#5c:FFF!3C8FFVt222$"9997;7L7LU7S7S/4#6s;GGG!4S9FMM&&*iHHHHr:   c                h   | j         sd S | j                            d          }|s]t          d          x}| j        d<   dt	          j        t          d          j                  z  }|                    || j                   d}d| j         v r| j         d         |_	        d| j         v rrt          d          
                                }| j         d         \
  |_        |_        |_        |_        |_        |_        |_        |_        |_        |_        ||_        d| j         v r| j         d         |_        d| j         v r| j         d         |_        d| j         v r| j         d         |_        d	| j         v r| j         d	         |_        d
| j         v r| j         d
         |_        d| j         v r%t7          d| j         d         z   dz             |_        d| j         v r| j         d         |_        d| j         v r| j         d         |_        d| j         v r |                    | j         d                    d| j         v r1|                      | j         d                   }|\  |_!        |_"        d}d| j         v r| j         d         |_#        d}d| j         v r| j         d         |_$        d}d| j         v r| j         d         |_%        d}d| j         v r| j         d         |_&        d}d }tO          ||j(                  |_(        |dk    r ||d           |dk    r ||d           |dk    r ||d           d S d S )NrJ       r   fstypepanosetypoascendertypodescendertypolinegap	winascent
windescentvendorz'''weightclass
widthclassunicoderangecodepageranger   xheight   	capheightloweropsize   upperopsizec                R    |D ]#}t          | |          st          | |d           $d S )Nr   )hasattrsetattr)r   attrsattrs      r8   	checkattrz%Builder.build_OS_2.<locals>.checkattr  s@     , ,ud++ ,E4+++, ,r:   )ulCodePageRange1ulCodePageRange2)sxHeight
sCapHeightusDefaultCharusBreakCharr   )usLowerOpticalPointSizeusUpperOpticalPointSize))r   r6   r   r   r   calcsizer   OS2_format_0r   fsTypePanosebFamilyTypebSerifStylebWeightbProportion	bContrastbStrokeVariation	bArmStylebLetterFormbMidlinebXHeightr4  sTypoAscendersTypoDescendersTypoLineGapusWinAscentusWinDescentr   	achVendIDusWeightClassusWidthClasssetUnicodeRangesbuild_codepages_rK  rL  rM  rN  rQ  rR  maxversion)r   r   datarl  r4  pagesrJ  s          r8   r   zBuilder.build_OS_2  sz   y 	F	f%% 	-(0(8(88EDIf%7+N6,B,B,OPPPDOOD$),,,ty  9X.ELty  #F++2244F 	(#""" ' "!ELTY&&"&)N";Edi''#'9_#=E DI%%!%=!9E$)## $	+ 6E49$$!%<!8Ety  &uty/B'BU'JKKEODI%%"&)M":E49$$!%<!8ETY&&""49^#<===di''))$)O*DEEE=B:E"E$:G	!!!Yy1ENG$)###y5EGDI%%,0Im,DE)GDI%%,0Im,DE)G	, 	, 	,
 GU]33a<<IeEFFFa<<I	 	 	 a<<IeSTTTTT <r:   c                    dD ]}|| j         v rt          | d|          t          |t                    r|| j         d<   d S t          |t                    r|| j         d<   d S t          |          )N)ElidedFallbackNameElidedFallbackNameIDz is already set.rq  rp  )r   r	   rV   r*  ry   AssertionError)r   valuer   tokens       r8   setElidedFallbackNamezBuilder.setElidedFallbackName&  s     D 	 	E
""%...   #
 eS!! 	(16DJ-...t$$ 	(/4DJ+,,, '''r:   c                H   d| j         vr
g | j         d<   |j        d | j         d         D             v rt          d|j         d|          |j        d | j         d         D             v rt          d|j         d|          | j         d                             |           d S )N
DesignAxesc              3  $   K   | ]}|j         V  d S rB   )rD   rC   rs     r8   rE   z(Builder.addDesignAxis.<locals>.<genexpr>9  s$      FFaeFFFFFFr:   z$DesignAxis already defined for tag "z".c              3  $   K   | ]}|j         V  d S rB   )	axisOrderry  s     r8   rE   z(Builder.addDesignAxis.<locals>.<genexpr>>  s$      #R#RAAK#R#R#R#R#R#Rr:   z+DesignAxis already defined for axis number r   )r   rD   r	   r|  r   )r   
designAxisr   s      r8   addDesignAxiszBuilder.addDesignAxis6  s    tz))')DJ|$>FFTZ-EFFFFF!Iz~III   #R#RL9Q#R#R#RRR!Uj>RUUU   	
< ''
33333r:   c                \   d| j         vr
g | j         d<   | j         d         D ]j}d |j        D             d |j        D             k    rDd |j        D             d |j        D             k    r |j        |j        k    rt	          d|          k| j         d                             |           d S )NAxisValueRecordsc                6    h | ]}|                                 S rR   asFearC   ns     r8   	<setcomp>z-Builder.addAxisValueRecord.<locals>.<setcomp>K  s     222q222r:   c                6    h | ]}|                                 S rR   r  r  s     r8   r  z-Builder.addAxisValueRecord.<locals>.<setcomp>L  s     ===!AGGII===r:   c                6    h | ]}|                                 S rR   r  r  s     r8   r  z-Builder.addAxisValueRecord.<locals>.<setcomp>M  s     :::1QWWYY:::r:   c                6    h | ]}|                                 S rR   r  r  s     r8   r  z-Builder.addAxisValueRecord.<locals>.<setcomp>N  s     AAA!AGGIIAAAr:   z8An AxisValueRecord with these values is already defined.)r   r  	locationsflagsr	   r   )r   axisValueRecordr   record_s       r8   addAxisValueRecordzBuilder.addAxisValueRecordE  s    TZ//-/DJ)*z"45 	 	G22GM222=='<===> >::(9:::AA'@AAAB BM_%:::%N   	
%&--o>>>>>r:   c                    | j         sd S | j                             d          }|st          dd           | j                             d          }i g }|D ]}g |j        <   |X|D ]T}i }|j        dk    r
|j        |d<   t          |j                  dk    r|j        d         }|j        }t          |          dk    r#|                    |d         |j	        d           t          |          dk    r*|                    |d         |d         |j	        d	           t          |          d
k    r%|\  }	}
}|                    |	|
||j	        d           |j                 
                    |           |                    d |j        D             |j	        d           |
                    |           Vfd|D             }| j                            d          }|s t          d          x}| j        d<   g |_	        d| j         v r9| j         d         }|                    |          }|st          d| dd           nd| j         v r| j         d         }t          j        | j        |||           d S )Nrw  zDesignAxes not definedr  r   r  r   )rs  r<   r@  )rs  linkedValuer<      )nominalValuerangeMinValuerangeMaxValuer<   c                4    i | ]}|j         |j        d          S )r   )rD   values)rC   is     r8   r   z&Builder.build_STAT.<locals>.<dictcomp>  s"    (S(S(S(S(S(Sr:   )r   r<   c                R    g | ]#}|j         |j        |j        |j                 d $S ))orderingrD   r<   r  )r|  rD   r  )rC   r   
axisValuess     r8   rU   z&Builder.build_STAT.<locals>.<listcomp>  sK     
 
 
  Ku$QU+	 
 
 
r:   r<   rq  zElidedFallbackNameID z; points to a nameID that does not exist in the "name" tablerp  )r  elidedFallbackName)r   r   r	   rD   r  r   r  r  updater  r   r6   r   getDebugNameotlbuildStatTable)r   r\   axisValueRecordsformat4_locationsrD   avr
valuesDictr   r  nominalminValmaxVal
designAxes	nameTabler	  r<   r  s                   @r8   r   zBuilder.build_STATW  s-   z 	Fz~~l++ 	B!":DAAA:>>*<==
 	% 	%C"$Jsw'' #9 #9
9q==*-)Jw's}%%**"}Q/H%_F6{{a''"))F1Isy*Q*QRRR6{{a''")))//5ay(+	    6{{a''28/"))071717(+		    x|,33J????%%(S(SS](S(S(S$'I    &,,Z8888
 
 
 
 
 
 

 IMM&))	 	!,4V,<,<<I	&) IO!TZ//Z 67F))&11D %#F # # # 	   "TZ//Z 45FI'%		
 	
 	
 	
 	
 	
r:   c                   i ddddddddd	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1fd2|D             }g }t          d          D ]X}|                    d3           t          |d4z  |dz   d4z            D ]'}||v r||xx         d5z  cc<   ||xx         d6z  cc<   (Yd7 |D             S )8Ni  r   i  r   i  r@  i  r  i     i  rC  i     i     i     ij     i     i     i     i     iQ     ie  0   ib  1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?   )ia  i`  i_  i^  i]  i\  iY  iW  iT  i  i  i  iR  i  c                (    g | ]}|v |         S rR   rR   )rC   p
pages2bitss     r8   rU   z,Builder.build_codepages_.<locals>.<listcomp>  s"    @@@!Z
1r:        10c                >    g | ]}t          |d d d                   S )N)r   )rC   r  s     r8   rU   z,Builder.build_codepages_.<locals>.<listcomp>  s*    333
1TTrT7##333r:   )r  r   )r   rn  bitsr  jr  s        @r8   rj  zBuilder.build_codepages_  s    
! 
! 
 ! 
 !	 

 ! 
 ! 
 ! 
 ! 
 ! 
  
  
  
  
  
 " 
  ! 
" # 
$ ? 
  
  

B A@@@u@@@q 	$ 	$ALL1r6AER<00 $ $99!HHHOHHHH!HHHOHHHH	$
 43U3333r:   c                   | j         s	| j        sd S t          j                    }d|_        |                     | j                   |_        |                     | j                  |_        t          d          }||_	        |S )Nr   rF   )
r~   r   r   rF   r  buildBASEAxis	HorizAxisVertAxisr   r   )r   r   r   s      r8   r   zBuilder.buildBASE  sw    $ 	T-A 	4}!++D,ABB**4+?@@&!!r:   c                H    t          j                    }d|_        ||_        |S Nr   )r   	BaseCoordr!  
Coordinate)r   ccoords      r8   buildBASECoordzBuilder.buildBASECoord  s$    "$$r:   c                p   |sd S |\  }}}t          j                    }t          j                    |_        ||j        _        t	          |          |j        _        t          j                    |_        g |j        _        t	          |          |j        _        t          |          D ]fd|D             }t          j                    }d         |_
        t          j                    |_        t          j                    |j        _        |                    d                   |j        j        _        g |j        j        _        t	          d                   |j        j        _        g |j        _        d         D ]9}|j        j        j                            |                     |                     :t          |          D ]\  }}	}
t          j                    }|                     |	          |_        |                     |
          |_        d|_        |dk    r||j        _        gt          j                    }||_        ||_        |j        j                            |           t	          |j        j                  |j        _        |j        j                            |           |S )Nc                H    g | ]}|d          d          k    |dd         S )r   r   NrR   )rC   recordr   s     r8   rU   z)Builder.buildBASEAxis.<locals>.<listcomp>  s:     ! ! !%6!9q	3I3Iqrr
3I3I3Ir:   r   r   r@  dflt)r   AxisBaseTagListBaselineTagr   BaseTagCountBaseScriptListBaseScriptRecordBaseScriptCountr   BaseScriptTag
BaseScript
BaseValuesindexDefaultIndexr  BaseCoordCountBaseLangSysRecordr   r  MinMaxMinCoordMaxCoordFeatMinMaxCountDefaultMinMaxBaseLangSysTagBaseLangSysCount)r   axisbasesscriptsminmaxminmax_for_scriptr  r  language	min_coord	max_coordminmax_recordlang_recordr   s                @r8   r  zBuilder.buildBASEAxis  s    	F!%w}#/11',$(+E

%&577/1,.1'll+Woo 	@ 	@F! ! ! !)/! ! ! .00F#)!9F  ( 3 5 5F+3+>+@+@F(8=F1I8N8NF(557F(2:=fQi..F(724F/AY V V!,6==d>Q>QRS>T>TUUUU289J2K2K L L.)Y ( 1 1)-)<)<Y)G)G&)-)<)<Y)G)G&01-v%%6CF%33"*"<">">K19K.)6K&%7>>{KKKK14!32 2F. 077????r:   c                6   t          j                    }|                                 |_        t	          j        | j        | j                  |_        t	          j	        | j
        | j        | j                  |_        |                                 |_        |                                 |_        |j        rdnd|_        | j        r| j                                        }|red|_        ||_        |                                }|                    |           d| j        v r%| j        d         j                            |           t3          |j        |j        |j        |j        |j        f          st5          |d          rt7          d          }||_        |S d S )Ni  r   i  rH   VarStorerG   )r   rG   buildGDEFGlyphClassDef_GlyphClassDefr  buildAttachListr   rZ   
AttachListbuildLigCaretListr   r   LigCaretListbuildGDEFMarkAttachClassDef_MarkAttachClassDefbuildGDEFMarkGlyphSetsDef_MarkGlyphSetsDefr  r[   finishr  optimizeremap_device_varidxesr6   r   r   rF  r   )r   r   store
varidx_mapr   s        r8   r   zBuilder.buildGDEF  s   }!99;;-d.@$-PP1 $"6
 
 #'"C"C"E"E $ ? ? A A%)%:Jzz
 		N(//11E N) %"^^--
**:666TY&&If%+AA*MMM"!'%
 
 	 T:&&	 f%%FFLM4r:   c                   | j         r$d | j                                         D             }nzi }| j        D ])}|                    |                                           *| j        j                                        D ](}|j        D ]}|	                                D ]}d||<   )|rt          j                    }||_        |S d S )Nc                     i | ]\  }\  }}||S rR   rR   rC   r   r  _s       r8   r   z3Builder.buildGDEFGlyphClassDef_.<locals>.<dictcomp><  s"    LLLFQq!LLLr:   r  )r   r   rk   r  inferGlyphClassesrW   markClassesr  definitionsglyphSetr   r   	classDefs)r   classesr   	markClassmarkClassDefr   r   s          r8   r  zBuilder.buildGDEFGlyphClassDef_:  s     		+LLt/C/I/I/K/KLLLGGG- ; ;v7799::::!^7>>@@ + +	$-$9 + +L!-!6!6!8!8 + +)*++  	+--F&FM4r:   c                    d | j                                         D             }|sd S t          j                    }||_        |S )Nc                     i | ]\  }\  }}||S rR   rR   r  s       r8   r   z8Builder.buildGDEFMarkAttachClassDef_.<locals>.<dictcomp>M  s"    DDDia!QQDDDr:   )r   r   r   r  r  )r   r  r   s      r8   r  z$Builder.buildGDEFMarkAttachClassDef_L  sL    DD4+;+A+A+C+CDDD	 	4,..$r:   c                    g }t          | j                                        d           D ]\  }}|                    |           t	          j        || j                  S )Nc                    | d         S r  rR   )items    r8   <lambda>z4Builder.buildGDEFMarkGlyphSetsDef_.<locals>.<lambda>W  s
    47 r:   r   )r   r   r   r   r  buildMarkGlyphSetsDefrZ   )r   setsglyphsid_s       r8   r  z"Builder.buildGDEFMarkGlyphSetsDef_T  sm    ! &&((.B.B
 
 
 	  	 KFC KK(t}===r:   c                    d| j         vr)t          d          | j         d<   i | j         d         _        | j        | j         d         j        t          <   d S )NDebg)r6   r   rm  rl   r   r   s    r8   r   zBuilder.buildDebg\  sP    "" ( 0 0DIf%'DIf"8<8M	&4555r:   c                R   |dv s
J |            | j         D ]	}d |_        
g }| j         D ]}|j        |k    r|                     |          }|                    |d u          }|t          d|j                  |D ]o}t          |          |_        t          t          |j                  |d           | j
        |         t          |j                  <   |                    |           pg }|D ]}	 |                    |                                           +# t          $ r(}t          t          |          |j                  |d }~wt          $ rM}| j
        |         t          |j                           j        }	t          t          |          |	          |d }~ww xY w|S )Nr   )is_named_lookupr   )r   r<   r   )rk   lookup_indexr   get_lookup_name_promote_lookup_typer	   r   r   r
   strrl   r   r5   r'   	Exception)
r   rD   r   r   r<   resolvedl	otLookupser   s
             r8   buildLookups_zBuilder.buildLookups_b  s   &&&&&&&m 	' 	'F"&Fm 	" 	"F|s""((00D11$dBR1SSH%4O  
  " "&)'ll#GV 11 H H H%c*3v/B+C+CD
 q!!!!" 	 	? 	?A?  ++++# A A A%c!ffaj99q@ ? ? ?05c!.6I6IJS%c!ffh77Q>? s%   5'D
F$'#E

F$AFF$c                
    t          t          |d                       }d|_        t          j                    |_        g |j        _        t          j                    |_        g |j        _        t          j                    |_        |                     |          |j        _	        i }i }i }d }t          | j                                        |          D ]>\  }}|\  }	}
}t          t                              d |D                                 }t!          |          }|dk    o|dk    }|                     ||          }t%          |          dk    r|s|s|D ]v}	 | j        |         t)          |                                       |          | j        |         t)          |          <   S# t,          $ r t/          j        d	           Y sw xY w||f}|                    |          }|t%          |j        j                  }t          j                    }||_        t          j                    |_        |                     |          |j        _        t=          |          |j        _        t%          |          |j        _         |j        j        !                    |           |||<   |"                    |	i           "                    |
g           !                    |           | j#                            |	|
f          |k    r|||	|
f<   @t          |                                          D ]\  }	}t          j                    }|	|_$        t          j%                    |_%        d |j%        _&        g |j%        _'        t          |                                          D ]\  }
}t          j'                    }t          j(                    |_(        d |j(        _)        |                    |	|
f          d
|j(        _*        n|j(        _*        fd|D             |j(        _+        t%          |j(        j+                  |j(        _,        |
dk    r|j(        |j%        _&        |
|_-        |j%        j'        !                    |           t%          |j%        j'                  |j%        _.        |j        j        !                    |           t%          |j        j                  |j        _/        t%          |j        j                  |j        _,        t%          |j        j	                  |j        _         |S )Nr   c                b    | d         d         | d         d         | d         d         | d         fS )Nr   r@  r   rR   )fs    r8   r  z#Builder.makeTable.<locals>.<lambda>  s+    AaDGQqT!Wad1gqt#D r:   r   c              3  2   K   | ]}|j         	|j         V  d S rB   )r*  )rC   r0  s     r8   rE   z$Builder.makeTable.<locals>.<genexpr>  s4        '(q~7QAN7Q7Q7Q7Q r:   rH   r  r   )r   zWfeaLib.Builder subclass needs upgrading to stash debug information. See fonttools#2065.r  c                     g | ]
}|k    |S rR   rR   )rC   r  req_feature_indexs     r8   rU   z%Builder.makeTable.<locals>.<listcomp>  s+     0 0 0!7H2H2HA2H2H2Hr:   r  )0getattrr   r  r   ScriptRecordr   FeatureRecordr   r3  Lookupr   rm   r   tupledictfromkeysr   any_feature_variationsr   rl   r-  _replaceKeyErrorr   r   r   
FeatureTagFeaturer(  FeatureParamsry   LookupListIndexr   r   r   rn   	ScriptTagScriptDefaultLangSysLangSysRecordLangSysLookupOrderReqFeatureIndexFeatureIndexr   
LangSysTagLangSysCountr   )r   rD   r   feature_indicesrequired_feature_indicesr  sortFeatureTagr   r   r   r   feature_taglookup_indices
lookup_keysize_featureforce_featureixfeature_keyfeature_indexfreclang_featuressreclangrecr9  s                          @r8   r   zBuilder.makeTable  s   ,#t,,.."#.00(*%$022*,'#.00"&"4"4S"9"9 #%  ED"4>#7#7#9#9~NNN 1	I 1	ILC(+%FD+ #  ,3     N #>22J&=B[F-BL 77SIIM>""a''']'$ 	 	:>:OPS:TB;hsh++ )#.s2ww77     MG     '
3K+//<<M$ #E$5$C D D-//"-'/11-1-D-D[-Q-Q*/3N/C/C,+.~+>+>(!/66t<<</<,vr**55dB??FF}UUU&**FD>::kII;H(&$8 &,GMMOO%<%< 	7 	7!FM(**D#DN"/++DK)-DK&(*DK%)/0C0C0E0E)F)F > >%o"022"*"2"4"4.2+$<$@$@&$$P$P!$,6<GO336GGO30 0 0 0.0 0 0, 037?3O/P/P,6>>18DK..)-G&K-44W===='*4;+D'E'EDK$)006666'*5+;+H'I'I$),U->-L)M)M&'*5+;+B'C'C$s   "AF22GGc                   i }d}| j                                         D ]\  \  }}}}g ||<   |                                D ]g\  }}	| j        |         }
g }|	D ]3}|j        |k    r|j        J |                    |j                   d}4||                             |
|f           h|r1|                                D ]\  }}t          | j        |||           d S d S )NFT)ro   r   r   r   r*  r   r+   r6   )r   r   	table_tagfeature_varshas_any_variationsr  rU  
variationsconditionsetbuildersraw_conditionsetindicesbconditions_and_lookupss                 r8   r   zBuilder.makeFeatureVariations  sL   "/3/G/M/M/O/O 	N 	N+Q;(*L%*4*:*:*<*< 	N 	N&h#'#6|#D ! . .Aw)++ >555NN1>222)-&&[)002BG1LMMMM	N  	7C7I7I7K7K  33'Iu&<k   	 	 r:   c                    | j                                         D ]I\  \  }}}}||k    r|                                D ]$\  }}t          fd|D                       r  dS %JdS )Nc              3  .   K   | ]}|j         k    V  d S rB   )r   )rC   rj  rb  s     r8   rE   z1Builder.any_feature_variations.<locals>.<genexpr>
  s*      >>qw)+>>>>>>r:   TF)ro   r   r   )r   rU  rb  r  r   re  rf  rg  s     `     r8   rA  zBuilder.any_feature_variations  s    +/+C+I+I+K+K 	  	 'OQ7Z+%%*4*:*:*<*<    &h>>>>X>>>>>  444   ur:   c                d    d | j                                         D             }||v r||         S d S )Nc                    i | ]\  }}||	S rR   rR   )rC   kvs      r8   r   z,Builder.get_lookup_name_.<locals>.<dictcomp>  s    <<<1q!<<<r:   )rg   r   )r   r   revs      r8   r+  zBuilder.get_lookup_name_  s<    << 3 9 9 ; ;<<<S==v;tr:   c                Z   |dk    r|dk    r| j         rt          d|          |dk    r| j        rt          d|          nd| _        ||f| j         v r;t          d|                                d|                                d|          | j                             ||f           d S )	NDFLTr  z_If "languagesystem DFLT dflt" is present, it must be the first of the languagesystem statementszRlanguagesystems using the "DFLT" script tag must precede all other languagesystemsTz"languagesystem  z" has already been specified)r`   r	   rf   stripadd)r   r   r   r  s       r8   add_language_systemzBuilder.add_language_system  s    VF 2 2t7U 2!=  
 V) %8   *.D&H!???!/<<>>>>8>>#3#3#3#35  
 	&**FH+=>>>>>r:   c                X    | j         rt          | j                   S t          dh          S )N)rt  r  )r`   r   r'  s    r8   get_default_language_systems_z%Builder.get_default_language_systems_-  s2     ) 	1T;<<<./000r:   c                    |r|dk    rt          d|          |                                 | _        d| _        d | _        || _        d| _        d | _        || _        |dk    r|| _	        || _
        d S d S )Nr   zL'useExtension' keyword for feature blocks is allowed only for 'aalt' featurert  r   )r	   rz  re   ra   rh   rj   rb   rc   rd   rq   rs   r   r   r<   use_extensions       r8   r   zBuilder.start_feature8  s     	TV^^!^   !% B B D D!%)-&+6>>"*D'4D$$$ >r:   c                l    | j         J d | _         d | _        d | _        d| _        d | _        d| _        d S )Nr   F)rj   re   rh   rb   rc   rd   r'  s    r8   r   zBuilder.end_featureI  sG    %111!% $)-&#r:   c                    || j         v rt          d|z  |          | j        dk    rt          d|          || _        d | j         |<   d | _        || _        | j        d| _        d | _        d S d S )Nz$Lookup "%s" has already been definedr   zpLookup blocks cannot be placed inside 'aalt' features; move it out, and then refer to it with a lookup statementr   )rg   r	   rj   ri   rh   rd   rb   rc   r|  s       r8   start_lookup_blockzBuilder.start_lookup_blockR  s    4&&&!6=x   !V++!L  
 !%$(D!+!) D-1D*** *)r:   c                p    | j         J d | _         d | _        d| _        | j        d| _        d | _        d S d S )NFr   )ri   rh   rd   rj   rb   rc   r'  s    r8   end_lookup_blockzBuilder.end_lookup_blocke  sP    $000 $#!) D-1D*** *)r:   c                    || j         v s
J |            d | _        | j         |         }||                     || j                   d S d S rB   )rg   rh   r   rj   )r   lookup_namer   s      r8   add_lookup_callzBuilder.add_lookup_calln  s`    d1111;111$[1''0FGGGGG r:   c                    || _         d S rB   )r|   )r   r   revisions      r8   set_font_revisionzBuilder.set_font_revisionu  s    %r:   c           	        t          |          dk    sJ | j        dv rt          d| j        z  |          | j        t          d|          d | _        | j        || j        f}| j                            |d         d|d         f          |dk    s|rrd d          | j        |<   n1| j                            |g           }fd|D             | j        |<   t          | j        |fg          | _        |r| j        |f}|| j	        v r`t          d	|
                                d
| j        
                                d| j	        |         
                                d|          | j        | j	        |<   d S d S )Nr  r   r  z7Language statements are not allowed within "feature %s"zCLanguage statements are not allowed within standalone lookup blocksr   r  r@  c                    g | ]}|v|	S rR   rR   )rC   xr   s     r8   rU   z(Builder.set_language.<locals>.<listcomp>  s#    "N"N"NQg=M=M1=M=M=Mr:   z	Language z	 (script z ) has already specified feature z as its required feature)r   rj   r	   rh   ra   rm   r   r   re   rn   rv  )r   r   r  include_defaultrequiredr   cur_lookupsr   s          @r8   set_languagezBuilder.set_languagex  s   8}}!!!!!%555!&(,(>?  
 !)!2  
  |Xt'=>.$$c!ffc!f%=>>/w")!!!*DN3 .,,S"55K"N"N"N"Nk"N"N"NDN3 )DL(+C*D E E 	B<*Cd---%o !((((**,,,,/4::<<<< 	 	 	 ,0+AD#C(((	B 	Br:   c                "   t          |          }| j                            |          }||S t          | j                  dz   }|| j        |<   |D ]=}|| j        v r&| j        |         \  }}t          d|d||          ||f| j        |<   >|S )Nr   Glyph z3 already has been assigned a MarkAttachmentType at )r   r   r   r   r   r	   )r   r   r#  r$  r   r  locs          r8   getMarkAttachClass_zBuilder.getMarkAttachClass_  s    6""%))&11?J$)**Q.*-' 	6 	6E((()%03%o49EE33@  
 (+HoDU##
r:   c                    t          |          }| j                            |          }||S t          | j                  }|| j        |<   |S rB   )r   r   r   r   )r   r   r#  r$  s       r8   getMarkFilterSet_zBuilder.getMarkFilterSet_  sQ    6"""&&v..?J$&'''*V$
r:   c                    |dz  }||                      ||          }||dz  z  }|#|                     ||          }|dz  }|| _        nd | _        || _        d S )N   r  r  )r  r  rc   rb   )r   r   rs  
markAttach
markFiltermarkAttachClassr   s          r8   set_lookup_flagzBuilder.set_lookup_flag  sz    !"66xLLO_12E! 228ZHHMDLE-:D**-1D* r:   c                    | j         dv rt          d| j         z  |          | j         t          d|          | j        |dfhk    rd S d | _        || _        d| _        d | _        |                     |ddd           d S )	Nr  z5Script statements are not allowed within "feature %s"zAScript statements are not allowed within standalone lookup blocksr  r   TF)r  r  )rj   r	   re   rh   ra   rb   rc   r  )r   r   r   s      r8   
set_scriptzBuilder.set_script  s    !%555!&(,(>?  
 !)!V    ff%5$666F)-&(FD5QQQQQr:   c                     g }|D ];}|"|                      fd|D                        &|                     d           <|S )zHelper for building chain contextual substitutions

        Given a list of lookup names, finds the LookupBuilder for each name.
        If an input name is None, it gets mapped to a None LookupBuilder.
        Nc                N    g | ]!}j                             |j                  "S rR   )rg   r   r<   )rC   r0  r   s     r8   rU   z1Builder.find_lookup_builders_.<locals>.<listcomp>  s,    IIIT(,,QV44IIIr:   )r   )r   r   lookup_buildersr   s   `   r8   find_lookup_builders_zBuilder.find_lookup_builders_  sr     ! 	- 	-J%&&IIIIjIII     &&t,,,,r:   c                    |D ]<}| j                             |t                                                    |           =d S rB   )r   r   r_   r  )r   r   r#  contourPointsr   s        r8   add_attach_pointszBuilder.add_attach_points  sM     	N 	NE))%77>>}MMMM	N 	Nr:   c                t    | j         dk    rt          d|          | j                            ||f           d S )Nr   z9Feature references are only allowed inside "feature aalt")rj   r	   rp   r   )r   r   featureNames      r8   add_feature_referencezBuilder.add_feature_reference  sK    !V++!KX   	""Hk#:;;;;;r:   c                :    | j                             |           d S rB   )rt   rw  r   rD   s     r8   add_featureNamezBuilder.add_featureName  s    s#####r:   c                :    | j                             |           d S rB   )rv   rw  r  s     r8   add_cv_parameterzBuilder.add_cv_parameter   s    $$$$$r:   c                Z    || j         v r| j         |xx         dz  cc<   dS d| j         |<   dS )zbAdds new items to ``self.cv_num_named_params_``
        or increments the count of existing items.r   N)rx   r  s     r8   add_to_cv_num_named_paramsz"Builder.add_to_cv_num_named_params  sJ     $+++%c***a/*****-.D%c***r:   c                F    | j         |                             |           d S rB   )rz   r   )r   	characterrD   s      r8   add_cv_characterzBuilder.add_cv_character  s$    C ''	22222r:   c                6    |r|||f| _         d S |||f| _        d S rB   )r   r~   )r   r  r  verticalr  s        r8   set_base_axiszBuilder.set_base_axis  s4     	=$)7F#;D   %*GV$<D!!!r:   c                    | j         dk    rt          d| j         z  |          ||||g| _        | j        D ]*\  }}||| j         f}| j                            |g            +d S )Nr  z9Parameters statements are not allowed within "feature %s")rj   r	   r{   re   rm   r   )	r   r   r  r  r  r  r   r   r   s	            r8   set_size_parameterszBuilder.set_size_parameters  s     !V++!&(,(>?  
 ",[*h O 1 	/ 	/LFD4!78CN%%c2....	/ 	/r:   c                   |                      |t          |          }|                                D ]\  }}||j        v r{||j        |         k    rDt                              dd                    |          d                    |          |           n&t          dd                    |          z  |          ||j        |<   d S )N)r   z7Removing duplicate substitution from "%s" to "%s" at %sr   z%Already defined substitution for "%s")r   r&   r   r   loginfor   r	   )r   r   r   r   r   rs  s         r8   add_any_subst_zBuilder.add_any_subst_$  s    !!(OW!MM!--// 	( 	(JCfn$$FN3///HHQ		#		%(( 	    *?$))C..P    #(FN3	( 	(r:   c                `   | j         dk    rP|                                D ]9\  }}| j                            |g           }||vr|                    |           :d S |s|s|r|                     ||||           d S |                     |d |                                D                        d S )Nr   c                    i | ]
\  }}|f|fS rR   rR   )rC   r   rs  s      r8   r   z,Builder.add_single_subst.<locals>.<dictcomp>D  s"    @@@*#ucVeX@@@r:   )rj   r   rr   r   r   add_single_subst_chained_r  )	r   r   prefixsuffixr   
forceChain
from_glyphto_glyphr   s	            r8   add_single_substzBuilder.add_single_subst7  s    !V++(/ * *$
H,77
BGG4''KK)))F 	V 	z 	**8VVWMMMF@@@@@	
 	
 	
 	
 	
r:   c                    |s|s|r|                      |||||           d S |                     ||ft          |          i           d S rB   )add_multi_subst_chained_r  r>  )r   r   r  r   r  replacementsr  s          r8   add_multiple_substzBuilder.add_multiple_substH  sr      	V 	z 	))(FE6<XXXFXu\**+	
 	
 	
 	
 	
r:   c                   | j         dk    r>| j                            |g                               fd|D                        d S |s|rj|                     |t
                    }|                    |          }||                     |t                    }| 	                    |||hg||g           n|                     |t                    }||j
        v rt          d|z  |          ||j
        |<   d S )Nr   c              3  $   K   | ]
}|v|V  d S rB   rR   )rC   r   r   s     r8   rE   z.Builder.add_alternate_subst.<locals>.<genexpr>W  s'      @@a!4------@@r:   z)Already defined alternates for glyph "%s")rj   rr   r   r   r   r   find_chainable_alternate_substr   r   _add_contextual_ruler   r	   )	r   r   r  r   r  replacementchainr   r   s	           @r8   add_alternate_substzBuilder.add_alternate_substT  s$   !V++(33E2>>DKK@@@@;@@@@@@F 	GV 	G$$X/GHHE99%@@F~11(<QRR%%eVugYQQQQ%%h0EFFFF%%%!;eCX   $/%   r:   c                    |s|s|r|                      ||||           d S t          |          st          d|          |                     |fdt	          j        | D                        d S )N!Empty glyph class in substitutionc                    i | ]}|fS rR   rR   )rC   r   r  s     r8   r   z.Builder.add_ligature_subst.<locals>.<dictcomp>{  s    CCC1QCCCr:   )add_ligature_subst_chained_allr	   r  	itertoolsproduct)r   r   r  r#  r  r  r  s        ` r8   add_ligature_substzBuilder.add_ligature_substi  s      	V 	z 	,,&&&+   F6{{ 	Q!"ExPPP 	CCCC	(96(BCCC	
 	
 	
 	
 	
r:   c                   t          |          dk    r| j        r| j        d         j        s| j        d         }t          |j                  dk    r|j        |k    r|j        |k    ru|j        |k    rjt          |j        d         t                    s"t          |j        d                   |j        d<   |j        d         	                    |d                    dS | j        
                    t          ||||                     dS )a4  Add a contextual rule, merging with the last rule if possible.

        Consecutive rules that share the same prefix, suffix, lookups, and have
        a single input position can be merged into one rule with broader input
        coverage. This produces more compact binary tables (often Format 3).
        r   r  r   N)r   rulesis_subtable_breakr#  r  r  r   rV   r_   r  r   r%   )r  r  r#  r  r   lasts         r8   r  zBuilder._add_contextual_rule~  s     v;;!EKO4U;r?DDK  A%%K6))K6))LG++!$+a.#66 9%(Q%8%8DKNA%%fQi000.vvvwOOPPPPPr:   c                   t          |          rt          |          rt          |          st          d|          |                     |t                    }|                     |          }|                     |||||           d S N,Empty glyph class in contextual substitution)r  r	   r   r   r  r  r   r   r  r#  r  r   r   r/  s           r8   add_chain_context_substzBuilder.add_chain_context_subst  s    6{{ 	#f++ 	S[[ 	!>   !!(,DEE--g66!!&&&&(KKKKKr:   c                   |rt          |          rt          |          st          d|          |                     |t                    }|                    |t
                    }||                     |t
                    }|j                            |           t          |
                                          }|                     |||g||g           d S r  )r  r	   r   r   find_chainable_substr!   r   r   r  r_   keysr  )r   r   r  r  r   r  subr  s           r8   r  z!Builder.add_single_subst_chained_  s     	c&kk 	V 	!>  
   +CDD((2DEE;**85GHHC7###7<<>>""!!%$#GGGGGr:   c                X   t          |          rt          |          st          d|          |                     |t                    }|                    ||it
                    }||                     |t
                    }||j        |<   |                     |||hg||g           d S r  )	r  r	   r   r   r  r   r   r   r  )r   r   r  r   r  r  r  r  s           r8   r  z Builder.add_multi_subst_chained_  s    6{{ 	#f++ 	!>     +CDD((%)>@TUU;**85IJJC)E!!%5'FSEJJJJJr:   c           
         t          |          rt          |          st          d|          |                     |t                    }|                    ||          }||                     |t                    }t          j        | D ]G}|j	        
                    ||          }	|	|k    rt          d| d|	 d| d|          ||j	        |<   H|j                            t          ||||g                     d S )Nr  z!Conflicting ligature sub rules: 'z' maps to 'z' and '')r  r	   r   r   find_chainable_ligature_substr   r   r  r  	ligaturesr   r  r   r%   )
r   r   r  r#  r  r  r  r  r   existings
             r8   r  z#Builder.add_ligature_subst_chained_  s)    6{{ 	#f++ 	!>     +CDD11&+FF;**85IJJC"F+ 	+ 	+A}((K88H;&&%eeeheeWbeee  
  +CM!.vvvuMMNNNNNr:   c                    |st          d|          |                     |t                    }|j                            |||f           d S )Nr  )r	   r   r    r  r   )r   r   
old_prefix
old_suffixr   r   s         r8   add_reverse_chain_single_substz&Builder.add_reverse_chain_single_subst  sU     	Q!"ExPPP!!(,JKKZW=>>>>>r:   c                   |s|s|r|                      ||||           d S |                     |t                    }|D ]\  }}|st          d|          |                     ||d          }	|D ]O}
	 |                    ||
|	           # t          $ r(}t          t          |          |j                  |d }~ww xY wd S )N%Empty glyph class in positioning ruleFpairPosContext)	add_single_pos_chained_r   r$   r	   makeOpenTypeValueRecordadd_posr'   r-  r   )r   r   r  r  posr  r   r#  rs  otValueRecordr   r2  s               r8   add_single_poszBuilder.add_single_pos  s)    	IV 	Iz 	I((663GGGGG%%h0@AAF!$ I I )?   !% < <eE != ! ! $ I IEIxFFFF+ I I I-c!ffajAAqHIII Is   2B


B<#B77B<c                   |r|st          d|          |                     |t                    }|                     ||d          }|                     ||d          }t	          t          t          |                              }	t	          t          t          |                              }
|                    ||	||
|           d S Nr  Tr  )r	   r   r#   r  r>  r   r_   addClassPair)r   r   glyphclass1value1glyphclass2value2r   v1v2cls1cls2s              r8   add_class_pair_poszBuilder.add_class_pair_pos  s     	U+ 	U!"I8TTT!!(N;;))(F4)PP))(F4)PPVC,,--..VC,,--..HdBb99999r:   c                    |r|st          d|          |                     |t                    }|                     ||d          }|                     ||d          }|                    |||||           d S r  )r	   r   r#   r  addGlyphPair)	r   r   glyph1r  glyph2r  r   r   r  s	            r8   add_specific_pair_poszBuilder.add_specific_pair_pos  s     	UV 	U!"I8TTT!!(N;;))(F4)PP))(F4)PPHfb&"=====r:   c           	         |st          d|          |                     |t                    }|                    |||                     ||          |                     ||                     d S Nr  )r	   r   r   add_attachmentmakeOpenTypeAnchor)r   r   
glyphclassentryAnchor
exitAnchorr   s         r8   add_cursive_poszBuilder.add_cursive_pos  s     	U!"I8TTT!!(,=>>##Hk::##Hj99		
 	
 	
 	
 	
r:   c                   |                      |t                    }|                     |||           |st          d|          |D ]C\  }}|                     ||          }|D ]%}||j                            |i           |j        <   &Dd S r  )r   r   
add_marks_r	   r  r  r   r<   )	r   r   r  marksr   
baseAnchorr  otBaseAnchorr   s	            r8   add_mark_base_poszBuilder.add_mark_base_pos  s    ""8-?@@'5111 	U!"I8TTT%* 	R 	R!J	228ZHHL R REQ((r229>BBR	R 	Rr:   c                4   |                      |t                    }g }|st          d|          |D ]V}i }|                     |||           |D ]#\  }}	|                     ||          ||	j        <   $|                    |           W|D ]}
||j        |
<   d S r  )r   r   r	   r  r  r<   r   r  )r   r   r  
componentsr   componentAnchorsr  anchors	ligAnchorr  r   s              r8   add_mark_lig_poszBuilder.add_mark_lig_pos  s    ""8->?? 	U!"I8TTT 	- 	-EGOOHgu555(- W W$	9*.*A*A(I*V*V	''##G,,,, 	8 	8E'7Ge$$	8 	8r:   c                   |                      |t                    }|                     |||           |st          d|          |D ]C\  }}|                     ||          }|D ]%}||j                            |i           |j        <   &Dd S r  )r   r   r  r	   r  	baseMarksr   r<   )	r   r   r  r  r   r  r  r  baseMarks	            r8   add_mark_mark_poszBuilder.add_mark_mark_pos+  s    ""8-?@@'5111 	U!"I8TTT%* 	! 	!!J	228ZHHL% ! ! ! !,,Xr::N !	! 	!r:   c                   t          |          rt          |          rt          |          st          d|          |                     |t                    }|                     |          }|                     |||||           d S )N0Empty glyph class in contextual positioning rule)r  r	   r   r   r  r  r  s           r8   add_chain_context_poszBuilder.add_chain_context_pos8  s    6{{ 	#f++ 	S[[ 	!BH   !!(,BCC--g66!!&&&&(KKKKKr:   c                   |rt          |          rt          |          st          d|          |                     |t                    }g }|j        D ]\  }}}}|                    |           g }	|D ]\  }
}||	                    d            |                     ||d          }|                    ||
|          }|0| 	                    |t                    }|                    |           |
D ]}|                    |||           |	                    |           t          |          t          |	          k    sJ ||	f            d |D             }
|                     |||
||	           d S )Nr#  Fr  c                    g | ]\  }}|S rR   rR   )rC   r   rq  s      r8   rU   z3Builder.add_single_pos_chained_.<locals>.<listcomp>[  s    $$$1!$$$r:   )r  r	   r   r   r  r   r   r  find_chainable_single_posr   r$   r  r   r  )r   r   r  r  r  r  targetsr  r   subsr#  rs  otValuer  r   s                  r8   r  zBuilder.add_single_pos_chained_A  s    	#f++ 	S[[ 	!BH     +ABB % 	$ 	$Aq!WNN7####  	 	MFE}D!!!22% 3  G 11'67KKC{..x9IJJs### 6 6HeW5555KK3xx3t99$$$sDk$$$$$$$$!!%FFFFFr:   c                j   |D ]\  }}|j         D ]}|j                                        D ]}||j        vr?|                     |t          j        |j                            }|j        |f|j        |<   J|j        |         d         }	|j        |	k    rt          d|d|	d|j        |          dS )z)Helper for add_mark_{base,liga,mark}_pos.r   r  z cannot be in both @z and @N)
r  r#  r  r  r  copydeepcopyanchorr<   r	   )
r   r   lookupBuilderr  r  r  r  markotMarkAnchorexistingMarkClasss
             r8   r  zBuilder.add_marks_^  s    ! 	 	LAy ) 5  (/88::  D=#666'+'>'>$dmL4G&H&H( ( 6?^\4R+D11,9,?,Ea,H)$>->>>"1/#'44):):):INN!L (# #  ?	 	r:   c                :    | j                             |           d S rB   )rh   add_subtable_break)r   r   s     r8   r4  zBuilder.add_subtable_breakq  s    ++H55555r:   c                    | j                             |d          \  }}|r||k    rt          d|d||          ||f| j         |<   d S )NNNr  z& was assigned to a different class at )r   r   r	   )r   r   r   
glyphClassoldClassoldLocations         r8   setGlyphClass_zBuilder.setGlyphClass_t  sr     $ 4 8 8 M M+ 	J..!/55++'  
 (28&<U###r:   c                    |D ]}|                      ||d           |D ]}|                      ||d           |D ]}|                      ||d           |D ]}|                      ||d           d S )Nr   r@  r  r  )r:  )r   r   
baseGlyphsligatureGlyphs
markGlyphscomponentGlyphsr   s          r8   add_glyphClassDefzBuilder.add_glyphClassDef~  s       	4 	4E%3333# 	4 	4E%3333 	4 	4E%3333$ 	4 	4E%3333	4 	4r:   c                6    |D ]}|| j         vr
|| j         |<   d S rB   )r   r   r   r#  caretsr   s        r8   add_ligatureCaretByIndex_z!Builder.add_ligatureCaretByIndex_  s7     	5 	5ED000.4$U+	5 	5r:   c                r    t          |t                    s|S |                     ||          \  }}|||fS |S rB   )rV   r   makeVariablePos)r   r   caretdefaultdevices        r8   makeLigCaretzBuilder.makeLigCaret  sH    %00 	L..x??V$$r:   c                X      fd|D             }|D ]}| j         vr
| j         |<   d S )Nc                <    g | ]}                     |          S rR   )rJ  )rC   rG  r   r   s     r8   rU   z3Builder.add_ligatureCaretByPos_.<locals>.<listcomp>  s)    III$##He44IIIr:   )r   rB  s   ``   r8   add_ligatureCaretByPos_zBuilder.add_ligatureCaretByPos_  sU    IIIII&III 	5 	5ED000.4$U+	5 	5r:   c                D    | j                             |||||g           d S rB   )r}   r   )r   r   r	  r-  r.  r/  r0  s          r8   add_name_recordzBuilder.add_name_record  s)    FJ	66JKKKKKr:   c                    || j         |<   d S rB   )r   r   r   rs  s      r8   add_os2_fieldzBuilder.add_os2_field  s    	#r:   c                    || j         |<   d S rB   )r   rQ  s      r8   add_hhea_fieldzBuilder.add_hhea_field      
3r:   c                    || j         |<   d S rB   )r   rQ  s      r8   add_vhea_fieldzBuilder.add_vhea_field  rU  r:   c                b   d| j         vrt          d|          || j        v rt          d| d|          d | j        D             fd|                                D             }d| j         v r2| j         d         j        fd|                                D             }|| j        |<   d S )	NrP   z?Cannot add feature variations to a font without an 'fvar' tablezCondition set 'z/' has the same name as a previous condition setc                B    i | ]}|j         |j        |j        |j        fS rR   )rS   minValuedefaultValuemaxValue)rC   r  s     r8   r   z,Builder.add_conditionset.<locals>.<dictcomp>  s:     
 
 
 L4=$*;T]K
 
 
r:   c           	     v    i | ]5\  }\  }}|t          ||                   t          ||                   f6S rR   )r,   )rC   rD   bottomtopaxisMaps       r8   r   z,Builder.add_conditionset.<locals>.<dictcomp>  sZ     
 
 

 #]fc	 vws|44sGCL11
 
 
r:   avarc                R    i | ]"\  }t          fd |D                       #S )c              3  P   K   | ] }v rt          |                   n|V  !d S rB   )r-   )rC   rq  r  r   s     r8   rE   z6Builder.add_conditionset.<locals>.<dictcomp>.<genexpr>  sU         =AGOO&q'$-888QR     r:   )r>  )rC   condition_ranger  r   s     @r8   r   z,Builder.add_conditionset.<locals>.<dictcomp>  sg       
 *D/	 e     ,      r:   )r6   r	   r   r\   r   segments)r   r   r   rs  r`  r   s       @@r8   add_conditionsetzBuilder.add_conditionset  s   ""!Q  
 $%%%!V#VVV  
 
	
 
 


 
 
 

 ',kkmm
 
 
 TYi'0G   
 .3[[]]  E $)C   r:   	varscalarr   returntuple[int, int | None]c                N   | j         | j        t          d|          |j        s| j                            |          dfS 	 | j                            || j                   \  }}n## t          $ r}t          d|          |d}~ww xY wd}||dk    rt          |          }||fS )zMake a pos statement from a VariableScalar, returning the default
        value, and optionally the variation index if the scalar genuinely
        requires variation too.Nz5Can't define a variable scalar in a non-variable fontz,Failed to compute deltas for variable scalarl    )r[   r^   r	   	does_varydefault_valueadd_to_variation_storer(   r*   )r   r   rg  rH  r  r2  rI  s          r8   rF  zBuilder.makeVariablePos  s     '4+>+F!G   " 	F&44Y??EE	!0GG4/ NGUU  	 	 	!> 	
 *!4!4%e,,Fs   #A' '
B1BBc                    d }t          |t                    s'|!t          j        t	          |                    }||fS |                     ||          \  }}||t          d|          ||fS )N4Can't define a device coordinate and variable scalar)rV   r   r  buildDevicer?  rF  r	   )r   rg  deviceTabler   rI  rH  s         r8   makeAnchorPoszBuilder.makeAnchorPos  s    )^44 	%&k):):;;f$$..xCC+"9!F   r:   c                   |dS d\  }}|j         &t          j        t          |j                             }|j        &t          j        t          |j                            }|                     |j        |j         |          \  }}|                     |j        |j        |          \  }}t          j        |||j	        ||          }|S )zast.Anchor --> otTables.AnchorNr6  )
xDeviceTabler  rp  r?  yDeviceTablerr  r  ybuildAnchorcontourpoint)r   r   r.  deviceXdeviceYr  rv  	otlanchors           r8   r  zBuilder.makeOpenTypeAnchor  s    >4%*od6+>&?&?@@G*od6+>&?&?@@G''&2ExPP
7''&2ExPP
7OAq&*=wPP	r:   c                    i | ]D\  }}}}|                     d           |d                                         |dd         z   ||fES )Reservedr   r   N)
startswithlower)rC   r  r<   isDevices       r8   r   zBuilder.<dictcomp>  sb        AtXqz**Q$qrr("T8$4  r:   c                :   |sdS i }| j                                         D ]\  }\  }}t          ||d          }|s|r%t          j        t          |                    ||<   Ct          |t                    rv|dd         dz   }	|	d                                         |	dd         z   }
t          ||
          rt          d|          | 
                    ||          \  ||<   }||||	<   |||<   |r|s|j        rddinddi}t          j        |          }|S )	z&ast.ValueRecord --> otBase.ValueRecordNr   r  Devicer   ro  YAdvanceXAdvance)_VALUEREC_ATTRSr   r:  r  rp  r?  rV   r   r  r	   rF  r  
buildValue)r   r   rq  r  vrastNameotNamer  valotDeviceNamefeaDeviceNamerI  valRecs                r8   r  zBuilder.makeOpenTypeValueRecord  se    	4+/+?+E+E+G+G 	! 	!'G'fh!Wd++C  ! _T#YY776

C00 !%ac{X5 ,Q 5 5 7 7,qrr:J J1m,, )NPX   &*%9%9(C%H%H"6
F%'-B|$ 6

 	D" 	D$%JC*aZOB##r:   NFrB   )F)rg  r   rh  ri  )b__name__
__module____qualname__r   r   r   r5   r   r   r   r   r   r   r   r  r(  r   r   ru  r~  r  r   rj  r   r  r  r   r  r  r  r   r3  r   r   rA  r+  rx  rz  r   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  staticmethodr  r  r  r  r  r  r  r  r	  r  r  r  r!  r$  r  r  r4  r:  r@  rD  rJ  rM  rO  rR  rT  rW  rf  rF  rr  r  r   valueRecordFormatr  r  rR   r:   r8   r4   r4   a   s        i    
       O G! G! G!R< < < <|  > > >
       :1* 1* 1*f
0 
0 
02 2 2": : :$ $ $- - -^  4RU RU RUh( ( ( 4 4 4? ? ?$S
 S
 S
j+4 +4 +4Z
 
 
  * * *X! ! !F  $  > > >N N N! ! !Fg g gR  .    ? ? ?2	1 	1 	15 5 5 5"$ $ $2 2 2 2&2 2 2H H H& & &+B +B +BZ  $  ! ! !R R R*   N N N< < <$ $ $% % %/ / /3 3 3 >@ = = = =/ / / ( ( (&
 
 
$ IN	
 	
 	
 	
/ / /*
 
 
* Q Q \Q,L L LH H HK K KO O O4? ? ?I I I(: : :> > >	
 	
 	
R R R8 8 8
! 
! 
!L L LG G G:  &6 6 6= = =
4 
4 
45 5 5
  5 5 5L L L            () () ()T   <     $*$<  O    r:   r4   r  )NNF)O
__future__r   fontTools.miscr   fontTools.misc.textToolsr   r   r   r   fontTools.feaLib.errorr	    fontTools.feaLib.lookupDebugInfor
   r   r   fontTools.feaLib.parserr   fontTools.feaLib.astr   fontTools.feaLib.variableScalarr   r   fontTools.otlLibr   r  fontTools.otlLib.maxContextCalcr   fontTools.ttLibr   r   fontTools.ttLib.tablesr   r   fontTools.otlLib.builderr   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   fontTools.otlLib.errorr'   fontTools.varLib.errorsr(   fontTools.varLib.varStorer)   fontTools.varLib.builderr*   fontTools.varLib.featureVarsr+   fontTools.varLib.modelsr,   r-   collectionsr.   r,  r  ior/   loggingr   r   	getLoggerr  r  r9   r?   objectr4   rR   r:   r8   <module>r     s"   " " " " " " " " " " " " E E E E E E E E E E E E 2 2 2 2 2 2         
 + * * * * * , , , , , , Q Q Q Q Q Q Q Q + + + + + + 6 6 6 6 6 6 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3                                   $ 4 3 3 3 3 3 / / / / / / ; ; ; ; ; ; 5 5 5 5 5 5 @ @ @ @ @ @ F F F F F F F F # # # # # #              				 g!!. . . .& 7<G G G G2M M M M Mf M M M M Mr:   