
    ]Mht                       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 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,m-Z-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8m9Z9 d dl:m;Z; d dl<Z<d dl=Z=d dl>m?Z? d dl@Z@d dlAZAd dlBZB e@jC        eD          ZEddZF	 ddZG G d deH          ZIdS )    )sstruct)Tagtostr
binary2numsafeEval)FeatureLibError)LookupDebugInfoLOOKUP_DEBUG_INFO_KEYLOOKUP_DEBUG_ENV_VAR)Parser)FeatureFile)VariableScalar)builder)
maxCtxFont)newTablegetTableModule)otBaseotTables)AlternateSubstBuilderChainContextPosBuilderChainContextSubstBuilderLigatureSubstBuilderMultipleSubstBuilderCursivePosBuilderMarkBasePosBuilderMarkLigPosBuilderMarkMarkPosBuilderReverseChainSingleSubstBuilderSingleSubstBuilderClassPairPosSubtableBuilderPairPosBuilderSinglePosBuilderChainContextualRuleAnySubstBuilder)OpenTypeLibError)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featurefiler/   r0   r   s        X/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/fontTools/feaLib/builder.pyaddOpenTypeFeaturesr6   3   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

    r.   N)r,   r   namer6   )r3   featuresfilenamer/   r0   r4   s         r5   addOpenTypeFeaturesFromStringr<   E   sD    & 5??++K $#k&FFFFFFr7   c                   x   e Zd Z ed dD                       Zd Zd^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!d" Z"d# Z#d$ Z$d% Z%d_d&Z&d' Z'd_d(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;	 d_d<Z<d= Z=d> Z>d? Z?d@ Z@dA ZAdB ZBdC ZCdD ZDdE ZEdF ZFdG ZGdH ZHdI ZIdJ ZJdK ZKdL ZLdM ZMdN ZNdO ZOdP ZPdQ ZQdR ZRdS ZSdT ZTdU ZUdV ZVdW ZWdX ZXdY ZYdZ ZZd[ Z[d\ e\j]        D             Z^d] Z_dS )`r1   c              #   4   K   | ]}t          |          V  d S N)r   ).0tags     r5   	<genexpr>zBuilder.<genexpr>_   s<           	C           r7   )
BASEGDEFGPOSGSUBOS/2headhhear9   vheaSTATc                     || _         t          |t                    r|d c| _        | _        nd |c| _        | _        |                                | _        d | _        d|v r5|d         j        | _        t          d | j        D                       | _        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 | _#        tI          tJ                    | _&        d | _'        d | _(        g | _)        d | _*        d | _+        i | _,        i | _-        i | _.        i | _/        i | _0        i | _1        i | _2        i | _3        i | _4        i | _5        i | _6        i | _7        i | _8        d S )Nfvarc                     g | ]	}|j         
S  )axisTag)r@   axs     r5   
<listcomp>z$Builder.__init__.<locals>.<listcomp>|   s    000000r7   r   F)rF   rE   )9r3   
isinstancer   	parseTreefilegetReverseGlyphMapglyphMapvarstorebuilderaxesr&   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_model_cache)selfr3   r4   s      r5   __init__zBuilder.__init__o   s   	 k;// 	:(3T%DNDII(,k%DNDI//11#T>>V)DI#800di000$ $D  *-&)-&# #%*"  $!%)+R 8 8"$#%  " "#(  UU!#!ee"$$&!)$// $! $#!!!"$!	


  r7   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: .rF   rH   rI   rJ   r9   rG   rK   rE   rF   r   c              3   *   K   | ]}|j         v V  d S r?   )r3   )r@   rA   r   s     r5   rB   z Builder.build.<locals>.<genexpr>   s*      <<Csdi<<<<<<r7   rD   rC   )(rT   r   rU   rW   parser2   supportedTables	frozensetjoinsortedNotImplementedErrorbuild_feature_aalt_
build_head
build_hhea
build_vhea
build_name
build_OS_2
build_STAT	makeTablerj   makeFeatureVariations
ScriptListScriptCountFeatureListFeatureCount
LookupListLookupCountr   r3   tableanyr   usMaxContext	buildGDEF	buildBASEosenvirongetr   	buildDebg)
r   r/   r0   unsupportedunsupported_stringrA   r   	fontTablegdefbases
   `         r5   r2   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	 	r7   c                      || j         |          }| j        |_        | j        |_        | j        |_        | j                            |           |S r?   )	r3   r]   
lookupflagr^   markFilterSetr_   	extensionrf   append)r   locationbuilder_classresults       r5   get_chained_lookup_zBuilder.get_chained_lookup_   sQ    ty(33 ,#=.V$$$r7   c                     | j         D ]8\  }}|||f}| j                            |g                               |           9d S r?   )r`   rh   
setdefaultr   )r   lookupfeature_namescriptlangkeys         r5   add_lookup_to_feature_zBuilder.add_lookup_to_feature_  sW     1 	> 	>LFD4.CN%%c2..55f====	> 	>r7   c                 @   | j         rIt          | j                   |k    r1| j         j        | j        k    r| j         j        | j        k    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)rc   typer   r]   r   r^   rd   r   r3   r_   r   rf   r   rb   re   r   )r   r   r   s      r5   get_lookup_zBuilder.get_lookup_  s0   	$T%&&-77 +t/??? .$2PPP##  	T%5 	!0  
 )=H==&*&6#)-)G&%)%8"T-...  	J9=9ID 56! 	R ''(8$:PQQQr7   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 rO   )rt   )r@   gas      r5   
<dictcomp>z/Builder.build_feature_aalt_.<locals>.<dictcomp>)  s$    KKKTQaaKKKr7   )Naaltc                 6    g | ]\  \  }}}}|k    ||||fS rO   rO   )r@   r   r   featurelookupsr9   s        r5   rR   z/Builder.build_feature_aalt_.<locals>.<listcomp>+  s>       4+VT7Wd?? w0"??r7   r   z
: Feature z has not been definedc              3   $   K   | ]
}|v|V  d S r?   rO   )r@   r   alts_for_glyphs     r5   rB   z.Builder.build_feature_aalt_.<locals>.<genexpr>;  s6       2 2&'1N3J3J3J3J3J3J2 2r7   c                 L    i | ]!\  }}t          |          d k    ||d         "S )   r   lenr@   glyphrepls      r5   r   z/Builder.build_feature_aalt_.<locals>.<dictcomp>>  s5     
 
 
*udCIIQRNNE47NNNr7   c                 @    i | ]\  }}t          |          d k    ||S )r   r   r   s      r5   r   z/Builder.build_feature_aalt_.<locals>.<dictcomp>A  s*    TTTc$iiRSmmmmmr7   c                 4    i | ]\  \  }}}}|d k    |||f|S )r   rO   )r@   r   r   r   r   s        r5   r   z/Builder.build_feature_aalt_.<locals>.<dictcomp>D  sA     
 
 
0'w&   T7#W   r7   )rk   rm   itemsrh   warningswarnrS   rt   getAlternateGlyphsr   extendrf   start_featurerl   rn   r   r   mappingr   
alternatesend_feature)r   r   r   r   r   r   r   
lookuplistr   r   altssinglemultiold_lookupssingle_lookupmulti_lookupr   r9   s                   @@r5   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#[)))))r7   c                    | j         sd S | j                            d          }|sPt          d          x}| j        d<   |                    d| j                   d|_        d|_        dx|_        |_        | j         |_	        d S )NrH   s6                                                         g      ?i<_l   e )
rw   r3   r   r   	decompiletableVersionmagicNumbercreatedmodifiedfontRevisionr   r   s     r5   r   zBuilder.build_headU  s    ! 	F	f%% 	8(0(8(88EDIf%OOJ	222!$E *E-77EMEN!/r7   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 )NrI   $                                          caretoffsetascender	descenderlinegap)
r   r3   r   r   r   r   caretOffsetascentdescentlineGapr   s     r5   r   zBuilder.build_hheaa  s    z 	F	f%% 	,(0(8(88EDIf%OOJ	222!+EDJ&& $
= 9E##:j1EL$*$$ J{3EM
"" Jy1EMMM #"r7   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 )NrJ   r   i  verttypoascenderverttypodescenderverttypolinegap)	r   r3   r   r   r   r   r   r   r   r   s     r5   r   zBuilder.build_vhear  s    z 	F	f%% 	,(0(8(88EDIf%OOJ	222!+E++:&89EL$*,, J':;EM
** J'89EMMM +*r7   c                 ^    d |j         D             }t          dd          D ]
}||vr|c S d S )Nc                     g | ]	}|j         
S rO   )nameID)r@   r9   s     r5   rR   z,Builder.get_user_name_id.<locals>.<listcomp>  s    77744;777r7      i  )namesrange)r   r   nameIDsuser_name_ids       r5   get_user_name_idzBuilder.get_user_name_id  sV    775;777!#u-- 	$ 	$L7**#### +	$ 	$r7   c                 T   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d          |_        | j                            |dfd          |_        | j                            |dfd          |_        | j                            |d          |_        | j                            |dfd          |_        t1          | j        |                   |_        | j        |         |_        |S )Nsizer   FeatUILabelNameIDFeatUITooltipTextNameIDSampleTextNameIDParamUILabelNameID_0)r   FeatureParamsSizerv   
DesignSizeSubfamilyID
RangeStartRangeEndrp   SubfamilyNameIDro   FeatureParamsStylisticSetVersionUINameIDrq   FeatureParamsCharacterVariantsFormatrr   r   r  r  r  rs   NumNamedParametersFirstParamUILabelNameIDr   ru   	CharCount	Character)r   rA   paramss      r5   buildFeatureParamszBuilder.buildFeatureParams  s   &==/11F %!"!d,,,)-)?)D&&)*&&D&&&) >d44444!;==!""&"8"=D'''<>>FFM'+'>'B'B)*A( (F$ .2-D-H-H/0!. .F* '+&=&A&A()1' 'F# )-(A(E(Ec1(M(MF%-1-D-H-H,-q. .F*  #4#6s#;<<F#237Fr7   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 )Nr9   r   )rx   r3   r   r   r  rS   intro   rp   r
  rq   rr   setNamesort)	r   r   r9   r  
platformID	platEncIDlangIDstringrA   s	            r5   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r7   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 )NrG       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      r5   	checkattrz%Builder.build_OS_2.<locals>.checkattr
  s@     , ,ud++ ,E4+++, ,r7   )ulCodePageRange1ulCodePageRange2)sxHeight
sCapHeightusDefaultCharusBreakCharr   )usLowerOpticalPointSizeusUpperOpticalPointSize))r   r3   r   r   r   calcsizer   OS2_format_0r   fsTypePanosebFamilyTypebSerifStylebWeightbProportion	bContrastbStrokeVariation	bArmStylebLetterFormbMidlinebXHeightr-  sTypoAscendersTypoDescendersTypoLineGapusWinAscentusWinDescentr   	achVendIDusWeightClassusWidthClasssetUnicodeRangesbuild_codepages_rD  rE  rF  rG  rJ  rK  maxversion)r   r   datare  r-  pagesrC  s          r5   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 <r7   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.rj  ri  )r   r   rS   r#  rt   AssertionError)r   valuer   tokens       r5   setElidedFallbackNamezBuilder.setElidedFallbackName!  s     D 	 	E
""%...   #
 eS!! 	(16DJ-...t$$ 	(/4DJ+,,, '''r7   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 r?   )rA   r@   rs     r5   rB   z(Builder.addDesignAxis.<locals>.<genexpr>4  s$      FFaeFFFFFFr7   z$DesignAxis already defined for tag "z".c              3   $   K   | ]}|j         V  d S r?   )	axisOrderrr  s     r5   rB   z(Builder.addDesignAxis.<locals>.<genexpr>9  s$      #R#RAAK#R#R#R#R#R#Rr7   z+DesignAxis already defined for axis number r   )r   rA   r   ru  r   )r   
designAxisr   s      r5   addDesignAxiszBuilder.addDesignAxis1  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3r7   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 rO   asFear@   ns     r5   	<setcomp>z-Builder.addAxisValueRecord.<locals>.<setcomp>F  s     222q222r7   c                 6    h | ]}|                                 S rO   r{  r}  s     r5   r  z-Builder.addAxisValueRecord.<locals>.<setcomp>G  s     ===!AGGII===r7   c                 6    h | ]}|                                 S rO   r{  r}  s     r5   r  z-Builder.addAxisValueRecord.<locals>.<setcomp>H  s     :::1QWWYY:::r7   c                 6    h | ]}|                                 S rO   r{  r}  s     r5   r  z-Builder.addAxisValueRecord.<locals>.<setcomp>I  s     AAA!AGGIIAAAr7   z8An AxisValueRecord with these values is already defined.)r   r  	locationsflagsr   r   )r   axisValueRecordr   record_s       r5   addAxisValueRecordzBuilder.addAxisValueRecord@  s    TZ//-/DJ)*z"45 	 	G22GM222=='<===> >::(9:::AA'@AAAB BM_%:::%N   	
%&--o>>>>>r7   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 )Nrp  zDesignAxes not definedry  r   r  r   )rl  r9   r9  )rl  linkedValuer9      )nominalValuerangeMinValuerangeMaxValuer9   c                 4    i | ]}|j         |j        d          S )r   )rA   values)r@   is     r5   r   z&Builder.build_STAT.<locals>.<dictcomp>~  s"    (S(S(S(S(S(Sr7   )r   r9   c                 R    g | ]#}|j         |j        |j        |j                 d $S ))orderingrA   r9   r  )ru  rA   r  )r@   r   
axisValuess     r5   rR   z&Builder.build_STAT.<locals>.<listcomp>  sK     
 
 
  Ku$QU+	 
 
 
r7   r9   rj  zElidedFallbackNameID z; points to a nameID that does not exist in the "name" tableri  )r  elidedFallbackName)r   r   r   rA   r  r   r  r  updater  r   r3   r   getDebugNameotlbuildStatTable)r   rY   axisValueRecordsformat4_locationsrA   avr
valuesDictr   r  nominalminValmaxVal
designAxes	nameTabler  r9   r  s                   @r5   r   zBuilder.build_STATR  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'%		
 	
 	
 	
 	
 	
r7   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  r9  i  r  i     i  r<  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 rO   rO   )r@   p
pages2bitss     r5   rR   z,Builder.build_codepages_.<locals>.<listcomp>  s"    @@@!Z
1r7        10c                 >    g | ]}t          |d d d                   S )N)r   )r@   r  s     r5   rR   z,Builder.build_codepages_.<locals>.<listcomp>  s*    333
1TTrT7##333r7   )r  r   )r   rg  bitsr  jr  s        @r5   rc  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3r7   c                    | j         s	| j        sd S t          j                    }d|_        |                     | j                   |_        |                     | j                  |_        t          d          }||_	        |S )Nr   rC   )
ry   rz   r   rC   r  buildBASEAxis	HorizAxisVertAxisr   r   )r   r   r   s      r5   r   zBuilder.buildBASE  sw    $ 	T-A 	4}!++D,ABB**4+?@@&!!r7   c                 H    t          j                    }d|_        ||_        |S Nr   )r   	BaseCoordr  
Coordinate)r   ccoords      r5   buildBASECoordzBuilder.buildBASECoord  s$    "$$r7   c                 V   |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                            |                     |                     :|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   NrO   )r@   recordr   s     r5   rR   z)Builder.buildBASEAxis.<locals>.<listcomp>  s:     ! ! !%6!9q	3I3Iqrr
3I3I3Ir7   r   r   r9  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                @r5   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U2C 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????r7   c                 h   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                            |           | j                                         t7          |j        |j        |j        |j        |j        f          st9          |d          rt;          d          }||_        |S d S )Ni  r   i  rE   VarStorerD   )r   rD   buildGDEFGlyphClassDef_GlyphClassDefr  buildAttachListr{   rW   
AttachListbuildLigCaretListr|   r}   LigCaretListbuildGDEFMarkAttachClassDef_MarkAttachClassDefbuildGDEFMarkGlyphSetsDef_MarkGlyphSetsDefr  rX   finishr  optimizeremap_device_varidxesr3   r   r   clearr   r?  r   )r   r   store
varidx_mapr   s        r5   r   zBuilder.buildGDEF  s   }!99;;-d.@$-PP1 $"6
 
 #'"C"C"E"E $ ? ? A A%)%:Jzz
 
	%(//11E N) %"^^--
**:666TY&&If%+AA*MMM""$$$"!'%
 
 	 T:&&	 f%%FFLM4r7   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 rO   rO   r@   r   r  _s       r5   r   z3Builder.buildGDEFGlyphClassDef_.<locals>.<dictcomp>8  s"    LLLFQq!LLLr7   r  )r~   r   rf   r  inferGlyphClassesrT   markClassesr  definitionsglyphSetr   r  	classDefs)r   classesr   	markClassmarkClassDefr   r   s          r5   r  zBuilder.buildGDEFGlyphClassDef_6  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4r7   c                     d | j                                         D             }|sd S t          j                    }||_        |S )Nc                      i | ]\  }\  }}||S rO   rO   r
  s       r5   r   z8Builder.buildGDEFMarkAttachClassDef_.<locals>.<dictcomp>I  s"    DDDia!QQDDDr7   )r   r   r   r  r  )r   r  r   s      r5   r  z$Builder.buildGDEFMarkAttachClassDef_H  sL    DD4+;+A+A+C+CDDD	 	4,..$r7   c                     g }t          | j                                        d           D ]\  }}|                    |           t	          j        || j                  S )Nc                     | d         S r  rO   )items    r5   <lambda>z4Builder.buildGDEFMarkGlyphSetsDef_.<locals>.<lambda>S  s
    47 r7   r   )r   r   r   r   r  buildMarkGlyphSetsDefrW   )r   setsglyphsid_s       r5   r   z"Builder.buildGDEFMarkGlyphSetsDef_P  sm    ! &&((.B.B
 
 
 	  	 KFC KK(t}===r7   c                     d| j         vr)t          d          | j         d<   i | j         d         _        | j        | j         d         j        t          <   d S )NDebg)r3   r   rf  rg   r
   r   s    r5   r   zBuilder.buildDebgX  sP    "" ( 0 0DIf%'DIf"8<8M	&4555r7   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   r9   r   )rf   lookup_indexr   get_lookup_name_promote_lookup_typer   r   r   r	   strrg   r   r2   r%   	Exception)
r   rA   r   r   r9   resolvedl	otLookupser   s
             r5   buildLookups_zBuilder.buildLookups_^  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                 b
    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                                 }|dk    o|dk    }|                     ||          }t#          |          dk    r|s|sw|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<   1t          |                                          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   r9  r   rO   )fs    r5   r  z#Builder.makeTable.<locals>.<lambda>  s+    AaDGQqT!Wad1gqt#D r7   r  c              3   2   K   | ]}|j         	|j         V  d S r?   )r$  )r@   r*  s     r5   rB   z$Builder.makeTable.<locals>.<genexpr>  s4        '(q~7QAN7Q7Q7Q7Q r7   rE   r  r   )r   zWfeaLib.Builder subclass needs upgrading to stash debug information. See fonttools#2065.i  c                      g | ]
}|k    |S rO   rO   )r@   r  req_feature_indexs     r5   rR   z%Builder.makeTable.<locals>.<listcomp>  s+     0 0 0!7H2H2HA2H2H2Hr7   r  )/getattrr   r  r   ScriptRecordr   FeatureRecordr   r-  Lookupr   rh   r   tupledictfromkeysany_feature_variationsr   rg   r'  _replaceKeyErrorr   r   r   
FeatureTagFeaturer!  FeatureParamsrt   LookupListIndexr   r   r   ri   	ScriptTagScriptDefaultLangSysLangSysRecordLangSysLookupOrderReqFeatureIndexFeatureIndexr   
LangSysTagLangSysCountr   )r   rA   r   feature_indicesrequired_feature_indicesr  sortFeatureTagr   r   r   r   feature_taglookup_indicessize_featureforce_featureixfeature_keyfeature_indexfreclang_featuressreclangrecr3  s                         @r5   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 ,	I ,	ILC(+%FD+ #  ,3     N &=B[F-BL 77SIIM>""a''']'$ 	 	:>:OPS:TB;hsh++ )#.s2ww77     MG     '7K+//<<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F##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)rj   r   r   r   r$  r   r(   r3   )r   r   	table_tagfeature_varshas_any_variationsr  rO  
variationsconditionsetbuildersraw_conditionsetindicesbconditions_and_lookupss                 r5   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   	 	 r7   c                     | j                                         D ]I\  \  }}}}||k    r|                                D ]$\  }}t          fd|D                       r  dS %JdS )Nc              3   .   K   | ]}|j         k    V  d S r?   )r   )r@   rc  r[  s     r5   rB   z1Builder.any_feature_variations.<locals>.<genexpr>  s*      >>qw)+>>>>>>r7   TF)rj   r   r   )r   rO  r[  r  r   r^  r_  r`  s     `     r5   r;  zBuilder.any_feature_variations  s    +/+C+I+I+K+K 	  	 'OQ7Z+%%*4*:*:*<*<    &h>>>>X>>>>>  444   ur7   c                 d    d | j                                         D             }||v r||         S d S )Nc                     i | ]\  }}||	S rO   rO   )r@   kvs      r5   r   z,Builder.get_lookup_name_.<locals>.<dictcomp>  s    <<<1q!<<<r7   )rb   r   )r   r   revs      r5   r%  zBuilder.get_lookup_name_  s<    << 3 9 9 ; ;<<<S==v;tr7   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   ra   stripadd)r   r   r   r  s       r5   add_language_systemzBuilder.add_language_system  s    VF 2 2t7U 2!=  
 V) %8   *.D&H!???!/<<>>>>8>>#3#3#3#35  
 	&**FH+=>>>>>r7   c                 X    | j         rt          | j                   S t          dh          S )N)rm  r  )r[   r   r!  s    r5   get_default_language_systems_z%Builder.get_default_language_systems_$  s2     ) 	1T;<<<./000r7   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' featurerm  r   )r   rs  r`   r\   rc   re   r]   r^   r_   rl   rn   r   r   r9   use_extensions       r5   r   zBuilder.start_feature/  s     	TV^^!^   !% B B D D!%)-&+6>>"*D'4D$$$ >r7   c                 l    | j         J d | _         d | _        d | _        d| _        d | _        d| _        d S )Nr   F)re   r`   rc   r]   r^   r_   r!  s    r5   r   zBuilder.end_feature@  sG    %111!% $)-&#r7   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   )rb   r   re   rd   rc   r_   r]   r^   ru  s       r5   start_lookup_blockzBuilder.start_lookup_blockI  s    4&&&!6=x   !V++!L  
 !%$(D!+!) D-1D*** *)r7   c                 p    | j         J d | _         d | _        d| _        | j        d| _        d | _        d S d S )NFr   )rd   rc   r_   re   r]   r^   r!  s    r5   end_lookup_blockzBuilder.end_lookup_block\  sP    $000 $#!) D-1D*** *)r7   c                     || j         v s
J |            d | _        | j         |         }||                     || j                   d S d S r?   )rb   rc   r   re   )r   lookup_namer   s      r5   add_lookup_callzBuilder.add_lookup_calle  s`    d1111;111$[1''0FGGGGG r7   c                     || _         d S r?   )rw   )r   r   revisions      r5   set_font_revisionzBuilder.set_font_revisionl  s    %r7   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  r9  c                     g | ]}|v|	S rO   rO   )r@   xr   s     r5   rR   z(Builder.set_language.<locals>.<listcomp>  s#    "N"N"NQg=M=M1=M=M=Mr7   z	Language z	 (script z ) has already specified feature z as its required feature)r   re   r   rc   r\   rh   r   r   r`   ri   ro  )r   r   r  include_defaultrequiredr   cur_lookupsr   s          @r5   set_languagezBuilder.set_languageo  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r7   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          r5   getMarkAttachClass_zBuilder.getMarkAttachClass_  s    6""%))&11?J$)**Q.*-' 	6 	6E((()%03%o49EE33@  
 (+HoDU##
r7   c                     t          |          }| j                            |          }||S t          | j                  }|| j        |<   |S r?   )r   r   r   r   )r   r   r  r  s       r5   getMarkFilterSet_zBuilder.getMarkFilterSet_  sQ    6"""&&v..?J$&'''*V$
r7   c                     |dz  }||                      ||          }||dz  z  }|#|                     ||          }|dz  }|| _        nd | _        || _        d S )N   r  r  )r  r  r^   r]   )r   r   rl  
markAttach
markFiltermarkAttachClassr   s          r5   set_lookup_flagzBuilder.set_lookup_flag  sz    !"66xLLO_12E! 228ZHHMDLE-:D**-1D* r7   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  )re   r   r`   rc   r\   r]   r^   r  )r   r   r   s      r5   
set_scriptzBuilder.set_script  s    !%555!&(,(>?  
 !)!V    ff%5$666F)-&(FD5QQQQQr7   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 rO   )rb   r   r9   )r@   r*  r   s     r5   rR   z1Builder.find_lookup_builders_.<locals>.<listcomp>  s,    IIIT(,,QV44IIIr7   )r   )r   r   lookup_buildersr   s   `   r5   find_lookup_builders_zBuilder.find_lookup_builders_  sr     ! 	- 	-J%&&IIIIjIII     &&t,,,,r7   c                     |D ]<}| j                             |t                                                    |           =d S r?   )r{   r   rZ   r  )r   r   r  contourPointsr   s        r5   add_attach_pointszBuilder.add_attach_points  sM     	N 	NE))%77>>}MMMM	N 	Nr7   c                 t    | j         dk    rt          d|          | j                            ||f           d S )Nr   z9Feature references are only allowed inside "feature aalt")re   r   rk   r   )r   r   featureNames      r5   add_feature_referencezBuilder.add_feature_reference  sK    !V++!KX   	""Hk#:;;;;;r7   c                 :    | j                             |           d S r?   )ro   rp  r   rA   s     r5   add_featureNamezBuilder.add_featureName  s    s#####r7   c                 :    | j                             |           d S r?   )rq   rp  r  s     r5   add_cv_parameterzBuilder.add_cv_parameter  s    $$$$$r7   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)rs   r  s     r5   add_to_cv_num_named_paramsz"Builder.add_to_cv_num_named_params  sJ     $+++%c***a/*****-.D%c***r7   c                 F    | j         |                             |           d S r?   )ru   r   )r   	characterrA   s      r5   add_cv_characterzBuilder.add_cv_character  s$    C ''	22222r7   c                 6    |r|||f| _         d S |||f| _        d S r?   )rz   ry   )r   r  r  verticalr  s        r5   set_base_axiszBuilder.set_base_axis  s4     	=$)7F#;D   %*GV$<D!!!r7   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")re   r   rv   r`   rh   r   )	r   r   r  r  r  r  r   r   r   s	            r5   set_size_parameterszBuilder.set_size_parameters  s     !V++!&(,(>?  
 ",[*h O 1 	/ 	/LFD4!78CN%%c2....	/ 	/r7   c                    |                      |t                    }|                                D ]\  }}||j        v r{||j        |         k    rDt                              dd                    |          d                    |          |           n&t          dd                    |          z  |          ||j        |<   d S )Nz7Removing 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   rl  s         r5   add_any_subst_zBuilder.add_any_subst_  s    !!(O<<!--// 	( 	(JCfn$$FN3///HHQ		#		%(( 	    *?$))C..P    #(FN3	( 	(r7   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 rO   rO   )r@   r   rl  s      r5   r   z,Builder.add_single_subst.<locals>.<dictcomp>;  s"    @@@*#ucVeX@@@r7   )re   r   rm   r   r   add_single_subst_chained_r  )	r   r   prefixsuffixr   
forceChain
from_glyphto_glyphr   s	            r5   add_single_substzBuilder.add_single_subst.  s    !V++(/ * *$
H,77
BGG4''KK)))F 	V 	z 	**8VVWMMMF@@@@@	
 	
 	
 	
 	
r7   c                     |s|s|r|                      |||||           d S |                     ||ft          |          i           d S r?   )add_multi_subst_chained_r  r8  )r   r   r  r   r  replacementsr  s          r5   add_multiple_substzBuilder.add_multiple_subst?  sr      	V 	z 	))(FE6<XXXFXu\**+	
 	
 	
 	
 	
r7   c                    | j         dk    r>| j                            |g                               fd|D                        d S |s|rd|                     |t
                    }|                     |t                    }|j        	                    t          ||hg||g                     n|                     |t                    }||j        v rt          d|z  |          ||j        |<   d S )Nr   c              3   $   K   | ]
}|v|V  d S r?   rO   )r@   r   r   s     r5   rB   z.Builder.add_alternate_subst.<locals>.<genexpr>N  s'      @@a!4------@@r7   z)Already defined alternates for glyph "%s")re   rm   r   r   r   r   r   r   rulesr   r#   r   r   )	r   r   r  r   r  replacementchainr   r   s	           @r5   add_alternate_substzBuilder.add_alternate_substK  s   !V++(33E2>>DKK@@@@;@@@@@@F 	GV 	G$$X/GHHE--h8MNNFK26UG9fvhWWXXXX%%h0EFFFF%%%!;eCX   $/%   r7   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 rO   rO   )r@   r   r  s     r5   r   z.Builder.add_ligature_subst.<locals>.<dictcomp>p  s    CCC1QCCCr7   )add_ligature_subst_chained_allr   r  	itertoolsproduct)r   r   r  r  r  r  r  s        ` r5   add_ligature_substzBuilder.add_ligature_subst^  s      	V 	z 	,,&&&+   F6{{ 	Q!"ExPPP 	CCCC	(96(BCCC	
 	
 	
 	
 	
r7   c           
      0   t          |          rt          |          rt          |          st          d|          |                     |t                    }|j                            t          ||||                     |                               d S N,Empty glyph class in contextual substitution)r  r   r   r   r  r   r#   r  r   r   r  r  r  r   r   s          r5   add_chain_context_substzBuilder.add_chain_context_substt  s    6{{ 	#f++ 	S[[ 	!>   !!(,DEE(B(B7(K(K 	
 	
 	
 	
 	
r7   c           	         |rt          |          rt          |          st          d|          |                     |t                    }|                    |t
                    }||                     |t
                    }|j                            |           |j	        
                    t          |t          |                                          g||g                     d S r  )r  r   r   r   find_chainable_substr   r   r   r  r  r   r#   rt   keys)r   r   r  r  r   r  subs          r5   r  z!Builder.add_single_subst_chained_  s     	c&kk 	V 	!>  
   +CDD((2DEE;**85GHHC7###gllnn)=)=(>NN	
 	
 	
 	
 	
r7   c                 z   t          |          rt          |          st          d|          |                     |t                    }|                    ||it
                    }||                     |t
                    }||j        |<   |j        	                    t          ||hg||g                     d S r  )r  r   r   r   r  r   r   r   r  r   r#   )r   r   r  r   r  r  r  r  s           r5   r  z Builder.add_multi_subst_chained_  s    6{{ 	#f++ 	!>     +CDD((%)>@TUU;**85IJJC)E.vy&3%PPQQQQQr7   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
             r5   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Nr7   c                     |st          d|          |                     |t                    }|j                            |||f           d S )Nr  )r   r   r   r  r   )r   r   
old_prefix
old_suffixr   r   s         r5   add_reverse_chain_single_substz&Builder.add_reverse_chain_single_subst  sU     	Q!"ExPPP!!(,JKKZW=>>>>>r7   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  rl  otValueRecordr   r,  s               r5   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  r8  r   rZ   addClassPair)r   r   glyphclass1value1glyphclass2value2r   v1v2cls1cls2s              r5   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9r7   c                     |r|st          d|          |                     |t                    }|                     ||d          }|                     ||d          }|                    |||||           d S r  )r   r   r!   r  addGlyphPair)	r   r   glyph1r  glyph2r  r   r  r  s	            r5   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&"=====r7   c           	          |st          d|          |                     |t                    }|                    |||                     ||          |                     ||                     d S Nr  )r   r   r   add_attachmentmakeOpenTypeAnchor)r   r   
glyphclassentryAnchor
exitAnchorr   s         r5   add_cursive_poszBuilder.add_cursive_pos  s     	U!"I8TTT!!(,=>>##Hk::##Hj99		
 	
 	
 	
 	
r7   c                    |                      |t                    }|                     |||           |st          d|          |D ]C\  }}|                     ||          }|D ]%}||j                            |i           |j        <   &Dd S r  )r   r   
add_marks_r   r  r  r   r9   )	r   r   r  marksr   
baseAnchorr  otBaseAnchorr   s	            r5   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r7   c                 4   |                      |t                    }g }|st          d|          |D ]V}i }|                     |||           |D ]#\  }}	|                     ||          ||	j        <   $|                    |           W|D ]}
||j        |
<   d S r  )r   r   r   r  r  r9   r   r  )r   r   r  
componentsr   componentAnchorsr  anchors	ligAnchorr  r   s              r5   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 	8r7   c                    |                      |t                    }|                     |||           |st          d|          |D ]C\  }}|                     ||          }|D ]%}||j                            |i           |j        <   &Dd S r  )r   r   r  r   r  	baseMarksr   r9   )	r   r   r  r  r   r	  r  r
  baseMarks	            r5   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 !	! 	!r7   c           
      0   t          |          rt          |          rt          |          st          d|          |                     |t                    }|j                            t          ||||                     |                               d S )N0Empty glyph class in contextual positioning rule)r  r   r   r   r  r   r#   r  r  s          r5   add_chain_context_poszBuilder.add_chain_context_pos  s    6{{ 	#f++ 	S[[ 	!BH   !!(,BCC(B(B7(K(K 	
 	
 	
 	
 	
r7   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            |j                            t          |d |D             ||	                     d S )Nr  Fr  c                     g | ]\  }}|S rO   rO   )r@   r   rj  s      r5   rR   z3Builder.add_single_pos_chained_.<locals>.<listcomp>A  s    (;(;(;tq!(;(;(;r7   )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  rl  otValuer  r   s                  r5   r  zBuilder.add_single_pos_chained_&  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$$$(;(;s(;(;(;VTJJ	
 	
 	
 	
 	
r7   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anchorr9   r   )
r   r   lookupBuilderr  r  r  r  markotMarkAnchorexistingMarkClasss
             r5   r  zBuilder.add_marks_D  s    ! 	 	LAy ) 5  (/88::  D=#666'+'>'>$dmL4G&H&H( ( 6?^\4R+D11,9,?,Ea,H)$>->>>"1/#'44):):):INN!L (# #  ?	 	r7   c                 :    | j                             |           d S r?   )rc   add_subtable_break)r   r   s     r5   r(  zBuilder.add_subtable_breakW  s    ++H55555r7   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         r5   setGlyphClass_zBuilder.setGlyphClass_Z  sr     $ 4 8 8 M M+ 	J..!/55++'  
 (28&<U###r7   c                     |D ]}|                      ||d           |D ]}|                      ||d           |D ]}|                      ||d           |D ]}|                      ||d           d S )Nr   r9  r  r  )r.  )r   r   
baseGlyphsligatureGlyphs
markGlyphscomponentGlyphsr   s          r5   add_glyphClassDefzBuilder.add_glyphClassDefd  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 	4r7   c                 6    |D ]}|| j         vr
|| j         |<   d S r?   )r}   r   r   r  caretsr   s        r5   add_ligatureCaretByIndex_z!Builder.add_ligatureCaretByIndex_p  s7     	5 	5ED000.4$U+	5 	5r7   c                 r    t          |t                    s|S |                     ||          \  }}|||fS |S r?   )rS   r   makeVariablePos)r   r   caretdefaultdevices        r5   makeLigCaretzBuilder.makeLigCaretu  sH    %00 	L..x??V$$r7   c                 X      fd|D             }|D ]}| j         vr
| j         |<   d S )Nc                 <    g | ]}                     |          S rO   )r>  )r@   r;  r   r   s     r5   rR   z3Builder.add_ligatureCaretByPos_.<locals>.<listcomp>~  s)    III$##He44IIIr7   )r|   r6  s   ``   r5   add_ligatureCaretByPos_zBuilder.add_ligatureCaretByPos_}  sU    IIIII&III 	5 	5ED000.4$U+	5 	5r7   c                 D    | j                             |||||g           d S r?   )rx   r   )r   r   r  r&  r'  r(  r)  s          r5   add_name_recordzBuilder.add_name_record  s)    FJ	66JKKKKKr7   c                     || j         |<   d S r?   )r   r   r   rl  s      r5   add_os2_fieldzBuilder.add_os2_field  s    	#r7   c                     || j         |<   d S r?   )r   rE  s      r5   add_hhea_fieldzBuilder.add_hhea_field      
3r7   c                     || j         |<   d S r?   )r   rE  s      r5   add_vhea_fieldzBuilder.add_vhea_field  rI  r7   c                 (   d| j         vrt          d|          d | j        D             fd|                                D             }d| j         v r2| j         d         j        fd|                                D             }|| j        |<   d S )NrM   z?Cannot add feature variations to a font without an 'fvar' tablec                 B    i | ]}|j         |j        |j        |j        fS rO   )rP   minValuedefaultValuemaxValue)r@   r  s     r5   r   z,Builder.add_conditionset.<locals>.<dictcomp>  s:     
 
 
 L4=$*;T]K
 
 
r7   c           	      v    i | ]5\  }\  }}|t          ||                   t          ||                   f6S rO   )r)   )r@   rA   bottomtopaxisMaps       r5   r   z,Builder.add_conditionset.<locals>.<dictcomp>  sZ     
 
 

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

 ',kkmm
 
 
 TYi'0G   
 .3[[]]  E $)C   r7   c                    | j         st          d|          | j        |_        |j        s	|j        d fS |                    | j         | j        | j                            d                    \  }}d }||dk    rt          |          }||fS )Nz5Can't define a variable scalar in a non-variable fontrU  l    )
rX   r   rY   	does_varyr<  add_to_variation_storer   r3   r   r'   )r   r   	varscalarr<  r  r=  s         r5   r:  zBuilder.makeVariablePos  s    # 	!G   	" 	+$d**"99 $"2DIMM&4I4I
 
 *!4!4%e,,Fr7   c                     d }t          |t                    s'|!t          j        t	          |                    }||fS |                     ||          \  }}||t          d|          ||fS )N4Can't define a device coordinate and variable scalar)rS   r   r  buildDevicer9  r:  r   )r   r^  deviceTabler   r=  r<  s         r5   makeAnchorPoszBuilder.makeAnchorPos  s    )^44 	%&k):):;;f$$..xCC+"9!F   r7   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.AnchorNr*  )
xDeviceTabler  ra  r9  yDeviceTablerc  r  ybuildAnchorcontourpoint)r   r   r"  deviceXdeviceYr  rg  	otlanchors           r5   r  zBuilder.makeOpenTypeAnchor  s    >4%*od6+>&?&?@@G*od6+>&?&?@@G''&2ExPP
7''&2ExPP
7OAq&*=wPP	r7   c                     i | ]D\  }}}}|                     d           |d                                         |dd         z   ||fES )Reservedr   r   N)
startswithlower)r@   r  r9   isDevices       r5   r   zBuilder.<dictcomp>  sb        AtXqz**Q$qrr("T8$4  r7   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   r`  YAdvanceXAdvance)_VALUEREC_ATTRSr   r4  r  ra  r9  rS   r   rp  r   r:  r  
buildValue)r   r   rj  r  vrastNameotNamerq  valotDeviceNamefeaDeviceNamer=  valRecs                r5   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##r7   NF)F)`__name__
__module____qualname__r   r   r   r2   r   r   r   r   r   r   r   r
  r!  r   r   rn  rw  r  r   rc  r   r  r  r   r  r  r   r   r-  r   r   r;  r%  rq  rs  r   r   ry  r{  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r(  r.  r4  r8  r>  rA  rC  rF  rH  rK  rZ  r:  rc  r  r   valueRecordFormatrv  r  rO   r7   r5   r1   r1   ^   s       i    
       O J J JX< < < <|  > > >
     81* 1* 1*f
0 
0 
02 2 2": : :$ $ $) ) )V  4RU RU RUh( ( ( 4 4 4? ? ?$S
 S
 S
j+4 +4 +4Z
 
 
  * * *X" " "H  $  > > >N N N! ! !Fb b bH  .    ? ? ?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	
 	
 	
 	
/ / /&
 
 
,

 

 


 
 
 R R RO O O4? ? ?I I I(: : :> > >	
 	
 	
R R R8 8 8
! 
! 
!

 

 


 
 
<  &6 6 6= = =
4 
4 
45 5 5
  5 5 5L L L            ") ") ")H  (     $*$<  O    r7   r1   r  )NNF)J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   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.varStorer&   fontTools.varLib.builderr'   fontTools.varLib.featureVarsr(   fontTools.varLib.modelsr)   r*   collectionsr+   r   r  ior,   loggingr   r   	getLoggerr  r  r6   r<   objectr1   rO   r7   r5   <module>r     s   " " " " " " E E E E E E E E E E E E 2 2 2 2 2 2         
 + * * * * * , , , , , , : : : : : : + + + + + + 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2f f f f ff f f f f fr7   