
    Li&                      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 eEj                  eI      ZJddZK	 ddZL G d deM      ZNy)    )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)StringIOc                B    t        | |      }|j                  ||       y)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        ^/home/ubuntu/crypto_trading_bot/.venv/lib/python3.12/site-packages/fontTools/feaLib/builder.pyaddOpenTypeFeaturesr9   6   s      dK(GMMuM-    c                \    t        t        |            }|r||_        t        | |||       y)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   s+    & 5?+K#k&Fr:   c            
         e Zd Z ed dD              Zd Zd`dZd Zd Zdad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%dbd%Z&d& Z'dbd'Z(d( Z)d) Z*d* Z+d+ Z,d, Z-d- Z.d. Z/d/ Z0d0 Z1d1 Z2d2 Z3d3 Z4d4 Z5d5 Z6d6 Z7g fd7Z8d8 Z9d9 Z:d: Z;	 dbd;Z<d< Z=d= Z>e?d>        Z@d? ZAd@ ZBdA ZCdB ZDdC ZEdD ZFdE ZGdF ZHdG ZIdH ZJdI ZKdJ ZLdK ZMdL ZNdM ZOdN ZPdO ZQdP ZRdQ ZSdR ZTdS ZUdT ZVdU ZWdV ZXdW ZYdX ZZ	 	 	 	 dcdYZ[dZ Z\d[ Z]e^j                  D  ci c]4  \  }}}}|j                  d\      s|d]   j                         |d^d z   ||f6 c}}}} Zbd_ Zcyc c}}}} w )dr4   c              #  2   K   | ]  }t        |        y wN)r   ).0tags     r8   	<genexpr>zBuilder.<genexpr>b   s        	C s   )
BASEGDEFGPOSGSUBOS/2headhhear<   vheaSTATc                4   || _         t        |t              r|d c| _        | _        nd |c| _        | _        |j                         | _        d | _        d|v r`|d   j                  | _        t        | j                  D cg c]  }|j                   c}      | _        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 | _'        tQ        tR              | _*        d | _+        d | _,        g | _-        d | _.        d | _/        i | _0        i | _1        i | _2        i | _3        i | _4        i | _5        i | _6        i | _7        i | _8        i | _9        i | _:        i | _;        y c c}w )Nfvarr   F)rI   rH   )<r6   
isinstancer   	parseTreefilegetReverseGlyphMapglyphMapvarstorebuilderaxesr)   axisTagr   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   axs       r8   __init__zBuilder.__init__r   s   	 k;/(3T%DNDI(,k%DNDI//1#T>V))DI#8&*ii00$D  #8"@"@"FD),&)-&# #%*"  $!%)+R 8"$#%  " "#(  U!#!e"$$&!)$/ $! $#!!!"$!	


 u 1s   >HNc                     j                   3t         j                   j                        j	                          _          j                   j                          | j                  }nEt        |      }| j                  z
  }|r)dj                  t        |            }t        d| d      d|v r j                          d|v r j                          d|v r j                          d|v r j                          d|v r j                          d	|v r j!                          d
|v r j#                          dD ]  }||vr j%                  |      } j&                  r j)                  ||       |j*                  j,                  dkD  s2|j.                  j0                  dkD  s|j2                  j4                  dkD  r"t7        |      x} j8                  |<   ||_        | j8                  v s j8                  |=  t=         fddD              r5d	 j8                  v r't?         j8                         j8                  d	   _         d|v r= jC                         }|r| j8                  d<   nd j8                  v r j8                  d= d|v r= jE                         }	|	r|	 j8                  d<   nd j8                  v r j8                  d= |s#tF        jH                  jK                  tL              r jO                          y y )N, z9The following tables were requested but are unsupported: .rI   rK   rL   rM   r<   rJ   rN   rH   rI   r   c              3  :   K   | ]  }|j                   v   y wrB   )r6   )rC   rD   r   s     r8   rE   z Builder.build.<locals>.<genexpr>   s     <Csdii<s   rG   rF   )(rR   r   rS   rU   parser5   supportedTables	frozensetjoinsortedNotImplementedErrorbuild_feature_aalt_
build_head
build_hhea
build_vhea
build_name
build_OS_2
build_STAT	makeTablerk   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   s   >>!#DIIt}}=CCEDNT">))Fv&F 4#7#77K%)YYvk/B%C")O)*!-  V$$&VOOVOOVOOVOOVOOVOO# 	#C& NN3'E''**5#6  ,,q0$$11A5##//!3-5c]:	DIIcN"'			!IIcN	# <+;<<499AT-7		-BDIIf*V>>#D$(		&!499$IIf%V>>#D$(		&!499$IIf%BJJNN#78NN 9r:   c                     || j                   |      }| j                  |_        | j                  |_        | j
                  |_        | j                  j                  |       |S rB   )	r6   r^   
lookupflagr_   markFilterSetr`   	extensionrg   append)r   locationbuilder_classresults       r8   get_chained_lookup_zBuilder.get_chained_lookup_   sS    tyy(3 ,,#==..V$r:   c                    | j                   D ]5  \  }}|||f}| j                  j                  |g       j                  |       7 y rB   )ra   ri   
setdefaultr   )r   lookupfeature_namescriptlangkeys         r8   add_lookup_to_feature_zBuilder.add_lookup_to_feature_  sF     11 	>LFD4.CNN%%c2.55f=	>r:   c                b   | j                   rt        | j                         |k(  rm| j                   j                  | j                  k(  rJ| j                   j                  | j
                  k(  r'| j                   j                  |      r| j                   S | j                  r| j                   rt        d|       || j                  |      | _         | j                  | j                   _        | j
                  | j                   _        | j                  | j                   _        | j                  j                  | j                          | j                  r#| j                   | j                  | j                  <   | j                  r&| j!                  | j                   | j                         | j                   S )NOWithin a named lookup block, all rules must be of the same lookup type and flag)rd   typer   r^   r   r_   can_add_mappingre   r	   r6   r`   r   rg   r   rc   rf   r   )r   r   r   mappings       r8   get_lookup_zBuilder.get_lookup_  sY   T%%&-7  ++t/?/??  ..$2P2PP  009###  T%5%5!0 
 )H=&*&6&6#)-)G)G&%)%8%8"T--.  9=9I9ID 5 56!! ''(8(8$:P:PQr:   c                |   | j                   s| j                  sy | j                  j                         D ci c]  \  }}|t        |       }}}| j                   dgz   D ]  \  }}| j                  j                         D 	cg c]  \  \  }}}}	||k(  r||||	f c}	}}}}|s!|dk7  rt        j                  |d|d       g|D ]z  \  }}}}	|	D ]n  }
t        |
t              s|
g}
|
D ]T  }|j                         j                         D ]1  \  }}|j                  |g       j                  fd|D               3 V p |  |j                         D ci c]  \  }}t        |      dk(  s||d    }}}|j                         D ci c]  \  }}t        |      dkD  s|| }}}|s|sy | j                  j                         D 	ci c]  \  \  }}}}	|dk7  r|||f|	 c}	}}}| _        | j                  }g | _        | j                  | j                  d| j                         |r| j!                  t"              }||_        |r| j!                  t&              }||_        | j+                          | j                  j                  |       y c c}}w c c}	}}}w c c}}w c c}}w c c}	}}}w )NNaaltr   z
: Feature z has not been definedc              3  ,   K   | ]  }|vs|  y wrB    )rC   galts_for_glyphs     r8   rE   z.Builder.build_feature_aalt_.<locals>.<genexpr><  s      2&'1N3J2   	   r   )rl   rn   itemsru   ri   warningswarnrQ   getAlternateGlyphsr   extendlenrg   start_featurerm   ro   r   r!   r   r   
alternatesend_feature)r   r   ar   r   r<   r   r   featurelookups
lookuplistr   glyphaltsreplsinglemultiold_lookupssingle_lookupmulti_lookupr   s                       @r8   r   zBuilder.build_feature_aalt_#  s   ""4+@+@
 .2-B-B-H-H-JKTQaajK
K"11^4DD 	NHd 9=8L8L8N 4+VT7Wd? w0G tv~xQUVW29 	.gw") J%j$7&0\
", +1+D+D+F+L+L+N KE4-7-B-B5"-MN*11 2+/2 		* /9.>.>.@
*udCIQRNE47N
 
 1;0@0@0BTc$iRSmTTe 59NN4H4H4J
 
0'w&  T7#W,

 mm4..8P8PQ ,,X7IJM$*M!++H6KLL&+L#[)U L&
 U
s)   JJ"J*3J*J0(J0J6
c                   | j                   sy | j                  j                  d      }|sRt        d      x}| j                  d<   |j	                  d| j                         d|_        d|_        dx|_        |_        | j                   |_	        y )NrK   s6                                                         g      ?i<_l   e )
rx   r6   r   r   	decompiletableVersionmagicNumbercreatedmodifiedfontRevisionr   r   s     r8   r   zBuilder.build_headV  sy    !!		f%(0(88EDIIf%OOJ		2!$E *E-77EMEN!//r:   c                   | j                   sy | j                  j                  d      }|s=t        d      x}| j                  d<   |j	                  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   |_	        y y )NrL   $                                          caretoffsetascender	descenderlinegap)
r   r6   r   r   r   r   caretOffsetascentdescentlineGapr   s     r8   r   zBuilder.build_hheab  s    zz		f%(0(88EDIIf%OOJ		2!+EDJJ& $

= 9E#::j1EL$**$ JJ{3EM

" JJy1EM #r:   c                   | j                   sy | j                  j                  d      }|s=t        d      x}| j                  d<   |j	                  d| j                         d|_        d| j                   v r| j                   d   |_        d| j                   v r| j                   d   |_        d| j                   v r| j                   d   |_        y y )NrM   r   i  verttypoascenderverttypodescenderverttypolinegap)	r   r6   r   r   r   r   r   r   r   r   s     r8   r   zBuilder.build_vheas  s    zz		f%(0(88EDIIf%OOJ		2!+E+::&89EL$**, JJ':;EM

* JJ'89EM +r:   c                    |j                   D cg c]  }|j                   }}t        dd      D ]
  }||vs|c S  y c c}w )N   i  )namesnameIDrange)r   r   r<   nameIDsuser_name_ids        r8   get_user_name_idzBuilder.get_user_name_id  sF    +0;;744;;77!#u- 	$L7*##	$ 8s   >c                   d}d }|dk(  rft        j                         }| j                  \  |_        |_        |_        |_        || j                  v r| j                  |   |_        |S d|_        |S || j                  v rP| j                  s	 |S || j                  v sJ t        j                         }d|_        | j                  |   |_        |S || j                  v rt        j                         }d|_        | j                   j#                  |df|      |_        | j                   j#                  |df|      |_        | j                   j#                  |df|      |_        | j*                  j#                  |d      |_        | j                   j#                  |df|      |_        t1        | j2                  |         |_        | j2                  |   |_        |S )N  sizer   FeatUILabelNameIDFeatUITooltipTextNameIDSampleTextNameIDParamUILabelNameID_0)r   FeatureParamsSizerw   
DesignSizeSubfamilyID
RangeStartRangeEndrq   SubfamilyNameIDrp   FeatureParamsStylisticSetVersionUINameIDrr   FeatureParamsCharacterVariantsFormatrs   r   r
  r  r  rt   NumNamedParametersFirstParamUILabelNameIDr   rv   	CharCount	Character)r   rD   
NO_NAME_IDparamss       r8   buildFeatureParamszBuilder.buildFeatureParams  s    
&=//1F %%!"!d,,,)-)?)?)D&< 9 *+&8 7 D&&&))0 - d44444!;;=!""&"8"8"=& % D'''<<>FFM'+'>'>'B'B)*J(F$ .2-D-D-H-H/0*.F* '+&=&=&A&A():'F# )-(A(A(E(Ec1(MF%-1-D-D-H-H,-z.F*  #4#6#6s#;<F#2237Fr:   c                   | j                   sy | j                  j                  d      }|s!t        d      x}| j                  d<   g |_        | j                   D ]  }|\  }}}}}t        |t              s|}|| j                  v rM|| j                  vr/| j                  |      | j                  |<   | j                  |   J | j                  |   }n]|d   | j                  v rL|| j                  vr/| j                  |      | j                  |<   | j                  |   J | j                  |   }|j                  |||||        |j                  j                          y )Nr<   r   )ry   r6   r   r   r  rQ   intrp   rq   r  rr   rs   setNamesort)	r   r   r<   r  
platformID	platEncIDlangIDstringrD   s	            r8   r   zBuilder.build_name  s\   {{		f%(0(88EDIIf%EKKK 	ID<@9FJ	66 fc*$,,,$"8"886:6K6KE6R..s3#55c:FFF!33C8FVt222$"9"997;7L7LU7S//4#66s;GGG!44S9FMM&&*iH!	I" 	r:   c                   | j                   sy | j                  j                  d      }|sat        d      x}| j                  d<   dt	        j
                  t        d      j                        z  }|j                  || j                         d}d| j                   v r| j                   d   |_	        d| j                   v rlt        d      j                         }| 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?                  | j                   d          d| j                   v r/| jA                  | 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        ||jP                        |_(        |dk\  r	 ||d       |dk\  r	 ||d       |dk\  r
 ||d       y y )NrJ       r   fstypepanosetypoascendertypodescendertypolinegap	winascent
windescentvendorz'''weightclass
widthclassunicoderangecodepageranger   xheight   	capheightloweropsize   upperopsizec                F    |D ]  }t        | |      rt        | |d        y )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bXHeightr+  sTypoAscendersTypoDescendersTypoLineGapusWinAscentusWinDescentr   	achVendIDusWeightClassusWidthClasssetUnicodeRangesbuild_codepages_rB  rC  rD  rE  rH  rI  maxversion)r   r   datarc  r+  pagesrA  s          r8   r   zBuilder.build_OS_2  s3   yy		f%(0(88EDIIf%7++N6,B,O,OPPDOOD$)),tyy 99X.ELtyy #F+224F 		(#""" ' "!ELTYY&"&))N";Edii'#'99_#=E DII%!%=!9E$))# $		+ 6E499$!%<!8Etyy &utyy/B'BU'JKEODII%"&))M":E499$!%<!8ETYY&""499^#<=dii'))$))O*DEE=B:E"E$:G		!!YYy1ENG$))##yy5EGDII%,0IIm,DE)GDII%,0IIm,DE)G	,
 GU]]3a<eEFa<	 a<eST r:   c                    dD ]  }|| j                   v st        | d|       t        |t              r|| j                   d<   y t        |t              r|| j                   d<   y t        |      )N)ElidedFallbackNameElidedFallbackNameIDz is already set.rh  rg  )r   r	   rQ   r!  ru   AssertionError)r   valuer   tokens       r8   setElidedFallbackNamezBuilder.setElidedFallbackName&  sz     D 	E

"%g-. 	 eS!16DJJ-.t$/4DJJ+, ''r:   c                j   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   j	                  |       y )N
DesignAxesc              3  4   K   | ]  }|j                     y wrB   )rD   rC   rs     r8   rE   z(Builder.addDesignAxis.<locals>.<genexpr>9  s     FaeeF   z$DesignAxis already defined for tag "z".c              3  4   K   | ]  }|j                     y wrB   )	axisOrderrp  s     r8   rE   z(Builder.addDesignAxis.<locals>.<genexpr>>  s     #RAAKK#Rrr  z+DesignAxis already defined for axis number r   )r   rD   r	   rt  r   )r   
designAxisr   s      r8   addDesignAxiszBuilder.addDesignAxis6  s    tzz)')DJJ|$>>FTZZ-EFF!6z~~6FbI  #RL9Q#RR!=j>R>R=SSTU  	

< ''
3r:   c                \   d| j                   vrg | j                   d<   | j                   d   D ]  }|j                  D ch c]  }|j                          c}|j                  D ch c]  }|j                          c}k(  sU|j                  D ch c]  }|j                          c}|j                  D ch c]  }|j                          c}k(  s|j                  |j                  k(  st        d|       | j                   d   j                  |       y c c}w c c}w c c}w c c}w )NAxisValueRecordsz8An AxisValueRecord with these values is already defined.)r   r  asFea	locationsflagsr	   r   )r   axisValueRecordr   record_ns        r8   addAxisValueRecordzBuilder.addAxisValueRecordE  s    TZZ/-/DJJ)*zz"45 	G$+MM2q2'6'<'<=!AGGI=>(/(9(9:1QWWY:'6'@'@A!AGGIABMM_%:%::%N 	 	

%&--o> 3=:As   D%DD$7D)c           	        | j                   sy | j                   j                  d      }|st        dd       | j                   j                  d      }i }g }|D ]  }g ||j                  <    |q|D ]k  }i }|j                  dkD  r|j                  |d<   t        |j                        dk(  r|j                  d   }|j                  }	t        |	      dk(  r!|j                  |	d   |j                  d       t        |	      dk(  r%|j                  |	d   |	d   |j                  d	       t        |	      d
k(  r&|	\  }
}}|j                  |
|||j                  d       ||j                     j                  |       |j                  |j                  D ci c]  }|j                  |j                  d    c}|j                  d       |j                  |       n |D cg c]4  }|j                  |j                  |j                  ||j                     d6 }}| j                  j                  d      }|s!t        d      x}| j                  d<   g |_	        d| j                   v r2| j                   d   }|j                  |      }|s-t        d| dd       d| j                   v r| j                   d   }t        j                   | j                  ||       y c c}w c c}w )Nrn  zDesignAxes not definedrx  r   r{  r   )rj  r<   r7  )rj  linkedValuer<      )nominalValuerangeMinValuerangeMaxValuer<   )r   r<   )orderingrD   r<   valuesr<   rh  zElidedFallbackNameID z; points to a nameID that does not exist in the "name" tablerg  )rz  elidedFallbackName)r   r   r	   rD   r{  r   rz  r  updater  r   rt  r6   r   getDebugNameotlbuildStatTable)r   rW   axisValueRecords
axisValuesformat4_locationsrD   avr
valuesDictr   r  nominalminValmaxValir   
designAxes	nameTabler  r<   s                      r8   r   zBuilder.build_STATW  s   zzzz~~l+!":DAA::>>*<=
 	%C"$Jsww	%'' #9
99q=*-))Jw's}}%*"}}Q/H%__F6{a'"))F1Isyy*QR6{a'")))//5ay(+		 6{a'28/"))071717(+			 x||,33J?%%EH]](S);(S$'II &,,Z8G#9X 
  KKuu$QUU+	

 
 IIMM&)	,4V,<<I		&) IO!TZZ/ZZ 67F))&1D%+F8 4# # 	  "TZZ/ZZ 45FII'%		
E )T
s   !K
$9K#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}|D cg c]  }||v s||    }}g }t        d      D ]L  }|j                  d2       t        |d3z  |dz   d3z        D ]!  }||v r||xx   d4z  cc<   ||xx   d5z  cc<   # N |D cg c]  }t        |d d d6          c}S c c}w c c}w )7Ni  r   i  r   i  r7  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       10)r  r   r   )r   re  
pages2bitspbitsr  js          r8   ra  zBuilder.build_codepages_  s    
! 
! 
 ! 
 !	 

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

B (-@!Z
1@@q 	$ALL1r6AER<0 $9!HOH!HOH	$	$ .33
1TrT7#33 A 4s   	CC>Cc                   | j                   s| j                  sy t        j                         }d|_        | j                  | j                         |_        | j                  | j                        |_        t        d      }||_	        |S )Nr   rF   )
rz   r{   r   rF   r  buildBASEAxis	HorizAxisVertAxisr   r   )r   r   r   s      r8   r   zBuilder.buildBASE  sn    $$T-A-A}}!++D,A,AB**4+?+?@&!r:   c                J    t        j                         }d|_        ||_        |S Nr   )r   	BaseCoordr  
Coordinate)r   ccoords      r8   buildBASECoordzBuilder.buildBASECoord  s$    ""$r:   c                   |sy |\  }}}t        j                         }t        j                         |_        ||j                  _        t	        |      |j                  _        t        j                         |_        g |j                  _        t	        |      |j                  _        t        |      D ]O  }|D cg c]  }|d   |d   k(  s|dd   }}t        j                         }|d   |_
        t        j                         |_        t        j                         |j                  _        |j                  |d         |j                  j                  _        g |j                  j                  _        t	        |d         |j                  j                  _        g |j                  _        |d   D ]@  }|j                  j                  j                  j%                  | j'                  |             B t        |      D ]  \  }	}
}t        j(                         }| j'                  |
      |_        | j'                  |      |_        d|_        |	dk(  r||j                  _        et        j"                         }|	|_        ||_        |j                  j"                  j%                  |        t	        |j                  j"                        |j                  _        |j                  j                  j%                  |       R |S c c}w )Nr   r   r7  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minmaxr   recordminmax_for_scriptr  language	min_coord	max_coordminmax_recordlang_records                 r8   r  zBuilder.buildBASEAxis  s   !%w}}#//1',$(+E
%&557/1,.1'l+Wo 	@F)/!%6!9q	3Iqr
! ! ..0F#)!9F  ( 3 3 5F+3+>+>+@F(8=F1I8NF((557F((2:=fQi.F((724F/AY V!!,,66==d>Q>QRS>TUV289J2K L.)Y ( 1)-)<)<Y)G&)-)<)<Y)G&01-v%6CF%%3"*"<"<">K19K.)6K&%%77>>{KL 25!!332F. 0077?=	@> =!s   9L
Lc                   t        j                         }| j                         |_        t	        j
                  | j                  | j                        |_        t	        j                  | j                  | j                  | j                        |_        | j                         |_        | j                         |_        |j                   rdnd|_        | j$                  r| j$                  j'                         }|red|_        ||_        |j+                         }|j-                  |       d| j.                  v r(| j.                  d   j0                  j-                  |       t3        |j                  |j                  |j                  |j                  |j                   f      st5        |d      rt7        d      }||_        |S y )Ni  r   i  rH   VarStorerG   )r   rG   buildGDEFGlyphClassDef_GlyphClassDefr  buildAttachListr|   rU   
AttachListbuildLigCaretListr}   r~   LigCaretListbuildGDEFMarkAttachClassDef_MarkAttachClassDefbuildGDEFMarkGlyphSetsDef_MarkGlyphSetsDefr  rV   finishr  optimizeremap_device_varidxesr6   r   r   r=  r   )r   r   store
varidx_mapr   s        r8   r   zBuilder.buildGDEF  si   }}!99;--d.@.@$--P11  $"6"6
 #'"C"C"E $ ? ? A%)%:%:z
((//1E) %"^^-
**:6TYY&IIf%++AA*M""!!''%%
 T:&f%FFLMr:   c                   | j                   r3| j                   j                         D ci c]  \  }\  }}|| }}}}ni }| j                  D ]!  }|j                  |j	                                # | j
                  j                  j                         D ]-  }|j                  D ]  }|j                         D ]  }d||<   	  / |rt        j                         }	||	_        |	S y c c}}}w )Nr  )r   r   rg   r  inferGlyphClassesrR   markClassesr  definitionsglyphSetr   r  	classDefs)
r   r   r  _classesr   	markClassmarkClassDefr   r   s
             r8   r  zBuilder.buildGDEFGlyphClassDef_:  s    /3/C/C/I/I/KLLFQq!tLGLG-- ;v779:;!^^77>>@ +	$-$9$9 +L!-!6!6!8 +)*+++ ++-F&FM Ms   C&c                    | j                   j                         D ci c]  \  }\  }}|| }}}}|sy t        j                         }||_        |S c c}}}w rB   )r   r   r   r  r  )r   r   r  r   r  r   s         r8   r  z$Builder.buildGDEFMarkAttachClassDef_L  sZ    +/+;+;+A+A+CDDia!QQTD	D,,.$ Es   Ac                    g }t        | j                  j                         d       D ]  \  }}|j                  |        t	        j
                  || j                        S )Nc                    | d   S r  r   )items    r8   <lambda>z4Builder.buildGDEFMarkGlyphSetsDef_.<locals>.<lambda>W  s
    47 r:   r   )r   r   r   r   r  buildMarkGlyphSetsDefrU   )r   setsglyphsid_s       r8   r  z"Builder.buildGDEFMarkGlyphSetsDef_T  s[    !  &&(.B
 	 KFC KK	  ((t}}==r:   c                    d| j                   vr,t        d      | j                   d<   i | j                   d   _        | j                  | j                   d   j                  t        <   y )NDebg)r6   r   rd  rh   r   r   s    r8   r   zBuilder.buildDebg\  sR    " ( 0DIIf%'DIIf"8<8M8M		&45r:   c                :   |dv sJ |       | j                   D ]	  }d |_         g }| j                   D ]  }|j                  |k7  r| j                  |      }|j	                  |d u      }|t        d|j                        |D ]g  }t        |      |_        t        t        |j                        |d       | j                  |   t        |j                        <   |j                  |       i  g }|D ]"  }	 |j                  |j                                $ |S # t        $ r%}t        t        |      |j                        |d }~wt        $ rJ}| j                  |   t        |j                           j                  }	t        t        |      |	      |d }~ww xY w)Nr   )is_named_lookupr   )r   r<   r   )rg   lookup_indexr   get_lookup_name_promote_lookup_typer	   r   r   r
   strrh   r   r5   r'   	Exception)
r   rD   r   r   r<   resolvedl	otLookupser   s
             r8   buildLookups_zBuilder.buildLookups_b  s   &&++&mm 	'F"&F	'mm 	"F||s"((0D11$dBR1SH%4OO 
  "&)'l#GV 1 H%%c*3v/B/B+CD
 q!"	"& 	 	?A?  +	?  $ A%c!fajj9q@ ?005c!..6IJSS%c!fh7Q>?s%   8D	F$ EFAFFc                &    t        t        |d              }d|_        t        j                         |_        g |j                  _        t        j
                         |_        g |j
                  _        t        j                         |_        | j                  |      |j                  _	        i }i }i }d }t        | j                  j                         |      D ]  \  }}|\  }	}
}t        t        j                  d |D                    }t!        |      }|dk(  xr |dk(  }| j#                  ||      }t%        |      dk(  r|s|sn|D ]G  }	 | j&                  |   t)        |         j+                  |      | j&                  |   t)        |      <   I ||f}|j3                  |      }|t%        |j
                  j                        }t        j                         }||_        t        j6                         |_        | j9                  |      |j6                  _        t=        |      |j6                  _        t%        |      |j6                  _         |j
                  j                  jC                  |       |||<   |jE                  |	i       jE                  |
g       jC                  |       | jF                  j3                  |	|
f      |k(  s|||	|
f<    t        |j                               D ]  \  }	}t        j                         }|	|_$        t        jJ                         |_%        d |jJ                  _&        g |jJ                  _'        t        |j                               D ]  \  }
}t        jN                         }t        jP                         |_(        d |jP                  _)        |j3                  |	|
f      }|d
|jP                  _*        n||jP                  _*        |D cg c]
  }||k7  s	| c}|jP                  _+        t%        |jP                  jV                        |jP                  _,        |
dk(  r|jP                  |jJ                  _&        |
|_-        |jJ                  jN                  jC                  |        t%        |jJ                  jN                        |jJ                  _.        |j                  j                  jC                  |        t%        |j                  j                        |j                  _/        t%        |j
                  j                        |j
                  _,        t%        |j                  j                        |j                  _         |S # t,        $ r t/        j0                  d	       Y Aw xY wc c}w )Nr   c                8    | d   d   | d   d   | d   d   | d   fS )Nr   r7  r   r   )fs    r8   r  z#Builder.makeTable.<locals>.<lambda>  s+    AaDGQqT!Wad1gqt#D r:   r	  c              3  N   K   | ]  }|j                   |j                     y wrB   )r  )rC   r  s     r8   rE   z$Builder.makeTable.<locals>.<genexpr>  s"      '(q~~7QANNs   %%rH   r	  r   )r   zWfeaLib.Builder subclass needs upgrading to stash debug information. See fonttools#2065.r  r  )0getattrr   r  r   ScriptRecordr   FeatureRecordr   r  Lookupr   ri   r   tupledictfromkeysr   any_feature_variationsr   rh   r  _replaceKeyErrorr   r   r   
FeatureTagFeaturer  FeatureParamsru   LookupListIndexr   r   r   rj   	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langrecreq_feature_indexr  s                            r8   r   zBuilder.makeTable  s   ,#t,."#..0(*%$002*,'#..0"&"4"4S"9 #%  E"4>>#7#7#9~N 1	ILC(+%FD+ # ,3 N #>2J&=B[F-BL 77SIM>"a']$ 	:>:O:OPS:TB;hsh+ ))#.s2w7	 '
3K+//<M$ #E$5$5$C$C D--/"-'//1-1-D-D[-Q*/3N/C,+.~+>(!!//66t</<,vr*55dB?FF}U&&**FD>:kI;H(&$8c1	Ih &,GMMO%< 	7!FM((*D#DN"//+DK)-DKK&(*DKK%)/0C0C0E)F >%o"002"*"2"2"4.2+$<$@$@&$$P!$,6<GOO36GGOO3  /0!7H2HA0, 037??3O3O/P,6>18DKK.)-G&KK--44W=)>* (+4;;+D+D'EDKK$))0069	7< (+5+;+;+H+H'I$),U->->-L-L)M&'*5+;+;+B+B'C$q   MMGP0s   AU)(
V3V)V
Vc                   i }d}| j                   j                         D ]  \  \  }}}}g ||<   |j                         D ]n  \  }}	| j                  |   }
g }|	D ]=  }|j                  |k7  r|j                  J |j                  |j                         d}? ||   j                  |
|f       p  |r1|j                         D ]  \  }}t        | j                  |||        y y )NFT)rk   r   r   r   r  r   r+   r6   )r   r   	table_tagfeature_varshas_any_variationsr   r<  
variationsconditionsetbuildersraw_conditionsetindicesbconditions_and_lookupss                 r8   r   zBuilder.makeFeatureVariations  s   "/3/G/G/M/M/O 	N+Q;(*L%*4*:*:*< 	N&h#'#6#6|#D ! .Aww)+ >>555NN1>>2)-&. [)002BG1LM	N	N 7C7I7I7K 33'IIu&<k r:   c                    | j                   j                         D ]>  \  \  }}}}||k7  r|j                         D ]  \  }}t        fd|D              s  y @ y)Nc              3  <   K   | ]  }|j                   k(    y wrB   )r   )rC   rR  rJ  s     r8   rE   z1Builder.any_feature_variations.<locals>.<genexpr>
  s     >qww)+>s   TF)rk   r   r   )r   r<  rJ  r   r   rM  rN  rO  s     `     r8   r(  zBuilder.any_feature_variations  sj    +/+C+C+I+I+K 	 'OQ7Z+%*4*:*:*<  &h>X>> 	  r:   c                |    | j                   j                         D ci c]  \  }}||
 }}}||v r||   S y c c}}w rB   )rc   r   )r   r   kvrevs        r8   r  zBuilder.get_lookup_name_  sE     $ 3 3 9 9 ;<1q!t<<S=v; =s   8c                H   |dk(  r|dk(  r| j                   rt        d|      |dk(  r| j                  rt        d|      d| _        ||f| j                   v r/t        d|j                         d|j                         d|      | j                   j	                  ||f       y )	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	   rb   stripadd)r   r   r   r  s       r8   add_language_systemzBuilder.add_language_system  s    VF 2t7U7U!= 
 V))%8  *.D&H!?!??!<<>8>>#35 
 	&&**FH+=>r:   c                \    | j                   rt        | j                         S t        dh      S )N)r[  r  )r\   r   r  s    r8   get_default_language_systems_z%Builder.get_default_language_systems_-  s-     ))T;;<<./00r:   c                    |r|dk7  rt        d|      | j                         | _        d| _        d | _        || _        d| _        d | _        || _        |dk(  r|| _	        || _
        y y )Nr   zL'useExtension' keyword for feature blocks is allowed only for 'aalt' featurer[  r   )r	   ra  ra   r]   rd   rf   r^   r_   r`   rm   ro   r   r   r<   use_extensions       r8   r   zBuilder.start_feature8  s|    TV^!^  !% B B D!%)-&+6>"*D'4D$ r:   c                t    | j                   J d | _         d | _        d | _        d| _        d | _        d| _        y )Nr   F)rf   ra   rd   r^   r_   r`   r  s    r8   r   zBuilder.end_featureI  sD    %%111!% $)-&#r:   c                    || j                   v rt        d|z  |      | j                  dk(  rt        d|      || _        d | j                   |<   d | _        || _        | j                  d| _        d | _        y y )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   )rc   r	   rf   re   rd   r`   r^   r_   rc  s       r8   start_lookup_blockzBuilder.start_lookup_blockR  s    4&&&!6=x  !!V+!L 
 !%$(D!+!!) D-1D* *r:   c                    | j                   J d | _         d | _        d| _        | j                  d| _        d | _        y y )NFr   )re   rd   r`   rf   r^   r_   r  s    r8   end_lookup_blockzBuilder.end_lookup_blocke  sM    $$000 $#!!) D-1D* *r:   c                    || j                   v sJ |       d | _        | j                   |   }|| j                  || j                         y y rB   )rc   rd   r   rf   )r   lookup_namer   s      r8   add_lookup_callzBuilder.add_lookup_calln  sT    d111>;>1$$[1''0F0FG r:   c                    || _         y rB   )rx   )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
                  j                  |d   d|d   f      }|dk(  s|r|r|d d  | j
                  |<   n>| j
                  j                  |g       }|D cg c]	  }||vs| c}| j
                  |<   t        | j                  |fg      | _        |r| j                  |f}|| j                  v rWt        d|j                         d	| j                  j                         d
| j                  |   j                         d|      | j                  | j                  |<   y y c c}w )Nr  r   r	  z7Language statements are not allowed within "feature %s"zCLanguage statements are not allowed within standalone lookup blocksr   r  r7  z	Language z	 (script z ) has already specified feature z as its required feature)r   rf   r	   rd   r]   ri   r   r   ra   rj   r]  )	r   r   r  include_defaultrequiredr   r   cur_lookupsxs	            r8   set_languagezBuilder.set_languagex  s   8}!!!!!%55!&(,(>(>? 
 !!)!2 
  ||Xt'='=>..$$c!ffc!f%=>/w")!*DNN3 ..,,S"5K.9"NQg=M1"NDNN3 )DLL(+C*D E<<*Cd---% !(**,//4::< 	 	 ,0+A+AD##C(  #Os   	FFc                <   t        |      }| j                  j                  |      }||S t        | j                        dz   }|| j                  |<   |D ]E  }|| j                  v r$| j                  |   \  }}t        d|d||      ||f| j                  |<   G |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?J$))*Q.*-' 	6E((())%03%493@ 
 (+HoDU#	6 
r:   c                    t        |      }| j                  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  }|| j                  ||      }||dz  z  }|&| j                  ||      }|dz  }|| _        || _        y d | _        || _        y )N   r  r  )rz  r|  r_   r^   )r   r   rj  
markAttach
markFiltermarkAttachClassr   s          r8   set_lookup_flagzBuilder.set_lookup_flag  sw    !"66xLO_12E! 228ZHMDLE-:D* ! .2D* r:   c                
   | j                   dv rt        d| j                   z  |      | j                   t        d|      | j                  |dfhk(  ry d | _        || _        d| _        d | _        | j                  |ddd       y )	Nrq  z5Script statements are not allowed within "feature %s"zAScript statements are not allowed within standalone lookup blocksr  r   TF)rr  rs  )rf   r	   ra   rd   r]   r^   r_   rv  )r   r   r   s      r8   
set_scriptzBuilder.set_script  s    !!%55!&(,(>(>? 
 !!)!V    ff%5$66)-&(FD5Qr:   c           	         g }|D ]X  }|C|j                  |D cg c]'  }| j                  j                  |j                        ) c}       H|j                  d       Z |S c c}w )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.
        N)r   rc   r   r<   )r   r   lookup_buildersr   r  s        r8   find_lookup_builders_zBuilder.find_lookup_builders_  sm     ! 	-J%&&>HIT((,,QVV4I  &&t,	- 	 Js   ,A"
c                x    |D ]5  }| j                   j                  |t                     j                  |       7 y rB   )r|   r   r[   r  )r   r   r  contourPointsr   s        r8   add_attach_pointszBuilder.add_attach_points  s6     	NE))%7>>}M	Nr:   c                t    | j                   dk7  rt        d|      | j                  j                  ||f       y )Nr   z9Feature references are only allowed inside "feature aalt")rf   r	   rl   r   )r   r   featureNames      r8   add_feature_referencezBuilder.add_feature_reference  s=    !!V+!KX  	""Hk#:;r:   c                :    | j                   j                  |       y rB   )rp   r^  r   rD   s     r8   add_featureNamezBuilder.add_featureName  s    s#r:   c                :    | j                   j                  |       y rB   )rr   r^  r  s     r8   add_cv_parameterzBuilder.add_cv_parameter   s    $r:   c                n    || j                   v r| j                   |xx   dz  cc<   yd| j                   |<   y)zbAdds new items to ``self.cv_num_named_params_``
        or increments the count of existing items.r   N)rt   r  s     r8   add_to_cv_num_named_paramsz"Builder.add_to_cv_num_named_params  s8     $+++%%c*a/*-.D%%c*r:   c                @    | j                   |   j                  |       y rB   )rv   r   )r   	characterrD   s      r8   add_cv_characterzBuilder.add_cv_character  s    C ''	2r:   c                2    |r|||f| _         y |||f| _        y rB   )r{   rz   )r   r  r  verticalr  s        r8   set_base_axiszBuilder.set_base_axis  s#    $)7F#;D %*GV$<D!r:   c                    | j                   dk7  rt        d| j                   z  |      ||||g| _        | j                  D ]0  \  }}||| j                   f}| j                  j                  |g        2 y )Nr	  z9Parameters statements are not allowed within "feature %s")rf   r	   rw   ra   ri   r   )	r   r   r  r  r  r  r   r   r   s	            r8   set_size_parameterszBuilder.set_size_parameters  s     !!V+!&(,(>(>? 
 ",[*h O 11 	/LFD4!7!78CNN%%c2.	/r:   c                l   | j                  |t        |      }|j                         D ]  \  }}||j                  v rg||j                  |   k(  r7t        j                  ddj                  |      dj                  |      |       nt        ddj                  |      z  |      ||j                  |<    y )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   rj  s         r8   add_any_subst_zBuilder.add_any_subst_$  s    !!(OW!M!--/ 	(JCfnn$FNN3//HHQ		#		%( 	 *?$))C.P   #(FNN3	(r:   c           	     f   | j                   dk(  rK|j                         D ]7  \  }}| j                  j                  |g       }||vs'|j	                  |       9 y |s|s|r| j                  ||||       y | j                  ||j                         D 	
ci c]
  \  }	}
|	f|
f c}
}	       y c c}
}	w r   )rf   r   rn   r   r   add_single_subst_chained_r  )r   r   prefixsuffixr   
forceChain
from_glyphto_glyphr   r   rj  s              r8   add_single_substzBuilder.add_single_subst7  s    !!V+(/ *$
H,,77
BG4'KK)* Vz**8VVWM07@*#ucVeX@	
@s   B-c                x    |s|s|r| j                  |||||       y | j                  ||ft        |      i       y rB   )add_multi_subst_chained_r  r%  )r   r   r  r   r  replacementsr  s          r8   add_multiple_substzBuilder.add_multiple_substH  sD     Vz))(FE6<XXu\*+	
r:   c                   | j                   dk(  r7| j                  j                  |g       j                  fd|D               y |s|rX| j	                  |t
              }|j                  |      }|| j                  |t              }| j                  |||hg||g       n| j	                  |t              }||j                  v rt        d|z  |      ||j                  |<   y )Nr   c              3  ,   K   | ]  }|vs|  y wrB   r   )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")rf   rn   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@;@@V$$X/GHE99%@F~11(<QR%%eVugYQ%%h0EFFF%%%!;eCX  $/% r:   c                    |s|s|r| j                  |||||       y t        |      st        d|      | j                  |t	        j
                  | D ci c]  }||f c}       y c c}w Nz!Empty glyph class in substitution)add_ligature_subst_chained_allr	   r  	itertoolsproduct)r   r   r  r  r  r  r  r   s           r8   add_ligature_substzBuilder.add_ligature_substi  st     Vz,,&&&+ 6{!"ExPP 	(1(9(96(BC1QC	
Cs   A'
c                (   t        |      dk(  r| j                  r| j                  d   j                  s| j                  d   }t        |j                        dk(  r|j                  |k(  r|j
                  |k(  rs|j                  |k(  rdt        |j                  d   t              s%t        |j                  d         |j                  d<   |j                  d   j                  |d          y| j                  j                  t        ||||             y)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   rQ   r[   r  r   r%   )r  r  r  r  r   lasts         r8   r  zBuilder._add_contextual_rule~  s     v;!EKKO4U4U;;r?DDKK A%KK6)KK6)LLG+!$++a.#6%(Q%8DKKNA%%fQi0.vvvwOPr:   c                    t        |      rt        |      rt        |      st        d|      | j                  |t              }| j	                  |      }| j                  |||||       y 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  sb    6{#f+S[!>  !!(,DE--g6!!&&&&(Kr:   c                j   |rt        |      rt        |      st        d|      | j                  |t              }|j	                  |t
              }|| j                  |t
              }|j                  j                  |       t        |j                               }| j                  |||g||g       y 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&kV!> 
   +CD((2DE;**85GHC7#7<<>"!!%$#Gr:   c                "   t        |      rt        |      st        d|      | j                  |t              }|j	                  ||it
              }|| j                  |t
              }||j                  |<   | j                  |||hg||g       y 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((%)>@TU;**85IJC)E!!%5'FSEJr:   c           
        t        |      rt        |      st        d|      | j                  |t              }|j	                  ||      }|| j                  |t              }t        j                  | D ]H  }|j                  j                  ||      }	|	|k7  rt        d| d|	 d| d|      ||j                  |<   J |j                  j                  t        ||||g             y )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11&+F;**85IJC""F+ 	+A}}((K8H;&%7s+hZwWbVccde 
  +CMM!	+ 	.vvvuMNr:   c                    |st        d|      | j                  |t              }|j                  j	                  |||f       y r  )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  s?    !"ExPP!!(,JKZW=>r:   c                V   |s|s|r| j                  ||||       y | j                  |t              }|D ]B  \  }}|st        d|      | j	                  ||d      }	|D ]  }
	 |j                  ||
|	        D y # t        $ r%}t        t        |      |j                        |d }~ww xY w)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  rj  otValueRecordr   r  s               r8   add_single_poszBuilder.add_single_pos  s    Vz((663G%%h0@AF!$ I)?  !% < <eE != ! $ IEIxFII , I-c!fajjAqHIs   "A::	B( B##B(c                >   |r|st        d|      | j                  |t              }| j                  ||d      }| j                  ||d      }t	        t        t        |                  }	t	        t        t        |                  }
|j                  ||	||
|       y 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    +!"I8TT!!(N;))(F4)P))(F4)PVC,-.VC,-.HdBb9r:   c                    |r|st        d|      | j                  |t              }| j                  ||d      }| j                  ||d      }|j	                  |||||       y r  )r	   r   r#   r  addGlyphPair)	r   r   glyph1r  glyph2r  r   r  r  s	            r8   add_specific_pair_poszBuilder.add_specific_pair_pos  sk    V!"I8TT!!(N;))(F4)P))(F4)PHfb&"=r:   c           	         |st        d|      | j                  |t              }|j                  ||| j	                  ||      | j	                  ||             y Nr  )r	   r   r   add_attachmentmakeOpenTypeAnchor)r   r   
glyphclassentryAnchor
exitAnchorr   s         r8   add_cursive_poszBuilder.add_cursive_pos  sZ    !"I8TT!!(,=>##Hk:##Hj9		
r:   c                
   | j                  |t              }| j                  |||       |st        d|      |D ]G  \  }}| j	                  ||      }|D ]+  }||j
                  j                  |i       |j                  <   - I y 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!"I8TT%* 	R!J	228ZHL REQ((r29>>BR	Rr:   c                (   | j                  |t              }g }|st        d|      |D ]Q  }i }| j                  |||       |D ]$  \  }}	| j	                  ||      ||	j
                  <   & |j                  |       S |D ]  }
||j                  |
<    y 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->?!"I8TT 	-EGOOHgu5(- W$	9*.*A*A(I*V	'W##G,	-  	8E'7Ge$	8r:   c                
   | j                  |t              }| j                  |||       |st        d|      |D ]G  \  }}| j	                  ||      }|D ]+  }||j
                  j                  |i       |j                  <   - I y 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!"I8TT%* 	!!J	228ZHL% ! ! !!,,Xr:NN!	!r:   c                    t        |      rt        |      rt        |      st        d|      | j                  |t              }| j	                  |      }| j                  |||||       y )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  sb    6{#f+S[!BH  !!(,BC--g6!!&&&&(Kr:   c                   |rt        |      rt        |      st        d|      | j                  |t              }g }|j                  D ]  \  }}}}|j                  |        g }	|D ]  \  }
}||	j                  d        | j                  ||d      }|j                  ||
|      }|'| j                  |t              }|j                  |       |
D ]  }|j                  |||        |	j                  |        t        |      t        |	      k(  s	J ||	f       |D cg c]  \  }}|	 }
}}| j                  |||
||	       y c c}}w )Nr  Fr  )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  rj  otValuer  r   r   rX  s                    r8   r  zBuilder.add_single_pos_chained_A  se   #f+S[!BH    +AB % 	$Aq!WNN7#	$  	MFE}D!22% 3 G 11'67KC{..x9IJs# 6HeW56KK	 3x3t9$1sDk1$ #$1!$$!!%F %s   $E	c                   |D ]  \  }}|j                   D ]  }|j                  j                         D ]  }||j                  vrK| j	                  |t        j                  |j                              }|j                  |f|j                  |<   \|j                  |   d   }	|j                  |	k7  s~t        d|d|	d|j                  |         y)z)Helper for add_mark_{base,liga,mark}_pos.r   rx  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 5 (//88: D=#6#66'+'>'>$dmmL4G4G&H( 6?^^\4R++D1,9,?,?,Ea,H)$>>->>"1#'):INN!L (# 	r:   c                :    | j                   j                  |       y rB   )rd   add_subtable_break)r   r   s     r8   r  zBuilder.add_subtable_breakq  s    ++H5r:   c                    | j                   j                  |d      \  }}|r||k7  rt        d|d||      ||f| j                   |<   y )NNNrx  z& was assigned to a different class at )r   r   r	   )r   r   r   
glyphClassoldClassoldLocations         r8   setGlyphClass_zBuilder.setGlyphClass_t  sZ     $ 4 4 8 8 M+J.!+' 
 (28&<U#r:   c                    |D ]  }| j                  ||d        |D ]  }| j                  ||d        |D ]  }| j                  ||d        |D ]  }| j                  ||d        y )Nr   r7  r  r  )r  )r   r   
baseGlyphsligatureGlyphs
markGlyphscomponentGlyphsr   s          r8   add_glyphClassDefzBuilder.add_glyphClassDef~  s       	4E%3	4# 	4E%3	4 	4E%3	4$ 	4E%3	4r:   c                N    |D ]   }|| j                   vs|| j                   |<   " y rB   )r~   )r   r   r  caretsr   s        r8   add_ligatureCaretByIndex_z!Builder.add_ligatureCaretByIndex_  s/     	5ED000.4$$U+	5r:   c                `    t        |t              s|S | j                  ||      \  }}|||fS |S rB   )rQ   r   makeVariablePos)r   r   caretdefaultdevices        r8   makeLigCaretzBuilder.makeLigCaret  s=    %0L..x?V$$r:   c                    |D cg c]  }| j                  ||       }}|D ]   }|| j                  vs|| j                  |<   " y c c}w rB   )r+  r}   )r   r   r  r$  r(  r   s         r8   add_ligatureCaretByPos_zBuilder.add_ligatureCaretByPos_  sU    BHI$##He4II 	5ED000.4$$U+	5 Js   Ac                D    | j                   j                  |||||g       y rB   )ry   r   )r   r   r  r$  r%  r&  r'  s          r8   add_name_recordzBuilder.add_name_record  s    FJ	66JKr:   c                "    || j                   |<   y rB   )r   r   r   rj  s      r8   add_os2_fieldzBuilder.add_os2_field  s    		#r:   c                "    || j                   |<   y rB   )r   r1  s      r8   add_hhea_fieldzBuilder.add_hhea_field      

3r:   c                "    || j                   |<   y rB   )r   r1  s      r8   add_vhea_fieldzBuilder.add_vhea_field  r5  r:   c                  
 d| j                   vrt        d|      || j                  v rt        d| d|      | j                  D ci c]0  }|j                  |j
                  |j                  |j                  f2 }}|j                         D ci c]'  \  }\  }}|t        |||         t        |||         f) }}}}d| j                   v rP| j                   d   j                  
|j                         D 	ci c]  \  }	t        
fd|	D               }}}	|| j                  |<   y c c}w c c}}}w c c}	}w )NrP   z?Cannot add feature variations to a font without an 'fvar' tablezCondition set 'z/' has the same name as a previous condition setavarc              3  H   K   | ]  }v rt        |         n|  y wrB   )r-   )rC   rX  r  r   s     r8   rE   z+Builder.add_conditionset.<locals>.<genexpr>  s2       =AGO&q'$-8QRRs   ")r6   r	   r   rW   rX   minValuedefaultValuemaxValuer   r,   segmentsr%  )r   r   r   rj  r  axisMaprD   bottomtopcondition_ranger   s       `     @r8   add_conditionsetzBuilder.add_conditionset  sv   "!Q 
 $%%%!!#&UV  		
 LL4==$*;*;T]]KK
 
 ',kkm
 

 #]fc	 vws|4sGCL1 
 
 TYYii'00G .3[[] 
 *D/	 e ,  E  $)C 5


s   	5D2,D7? D>c                \   | j                   | j                  t        d|      |j                  s| j                  j	                  |      dfS 	 | j                  j                  || j                         \  }}d}||dk7  rt        |      }||fS # t        $ r}t        d|      |d}~ww xY w)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    )rV   rZ   r	   	does_varydefault_valueadd_to_variation_storer(   r*   )r   r   	varscalarr)  r  r  r*  s          r8   r'  zBuilder.makeVariablePos  s     '4+>+>+F!G  ""&&44Y?EE	!00GG4//NGU *!4%e,F  	!>	s   )B 	B+B&&B+c                    d }t        |t              s$|t        j                  t	        |            }||fS | j                  ||      \  }}||t        d|      ||fS )N4Can't define a device coordinate and variable scalar)rQ   r   r  buildDevicer&  r'  r	   )r   rH  deviceTabler   r*  r)  s         r8   makeAnchorPoszBuilder.makeAnchorPos  st    )^4&k):;f$$..xC+"9!F  r:   c                   |yd\  }}|j                   (t        j                  t        |j                               }|j                  (t        j                  t        |j                              }| j                  |j                  |j                   |      \  }}| j                  |j                  |j                  |      \  }}t        j                  |||j                  ||      }|S )zast.Anchor --> otTables.AnchorNr  )
xDeviceTabler  rK  r&  yDeviceTablerM  ru  ybuildAnchorcontourpoint)r   r   r  deviceXdeviceYru  rQ  	otlanchors           r8   r  zBuilder.makeOpenTypeAnchor  s    >%*ood6+>+>&?@G*ood6+>+>&?@G''&2E2ExP
7''&2E2ExP
7OOAq&*=*=wP	r:   Reservedr   r   c                   |syi }| j                   j                         D ]  \  }\  }}t        ||d      }|s|r"t        j                  t        |            ||<   =t        |t              rZ|dd dz   }	|	d   j                         |	dd z   }
t        ||
      rt        d|      | j                  ||      \  ||<   }||||	<   |||<    |r|s|j                  rddinddi}t        j                  |      }|S )	z&ast.ValueRecord --> otBase.ValueRecordNr   r  Devicer   rJ  YAdvanceXAdvance)_VALUEREC_ATTRSr   r!  r  rK  r&  rQ   r   lowerr	   r'  r  
buildValue)r   r   rX  r  vrastNameotNameisDevicevalotDeviceNamefeaDeviceNamer*  valRecs                r8   r  zBuilder.makeOpenTypeValueRecord  s   +/+?+?+E+E+G 	!'G'fh!Wd+C __T#Y76
C0%a{X5 ,Q 5 5 7,qr:J J1m,)NPX  &*%9%9(C%H"6
F%'-B|$ 6
#	!& "$%JJ*aZOB#r:   NFrB   )F)rH  r   returnztuple[int, int | None])d__name__
__module____qualname__r   r   r   r5   r   r   r   r   r   r   r   r  r  r   r   rl  rv  r  r   ra  r   r  r  r   r  r  r  r   r  r   r   r(  r  r_  ra  r   r   rg  ri  rl  ro  rv  rz  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  r  r  r"  r%  r+  r-  r/  r2  r4  r7  rC  r'  rM  r  r   valueRecordFormat
startswithr]  r\  r  )rC   r   r<   rb  s   0000r8   r4   r4   a   s     
  O G!R<|>
 :1*f
02":$-^4RUh( 4?$S
j+4Z
*X!F$>N!FgR.?2	15"$2&2H&+BZ$!R* N<$%/3 >@ =/ (&
$ IN	
/*
* Q Q,LHKO4?I(:>	
R8
!LG:&6=
45
5L  ()T#1	<  %+$<$<  AtXqz* 	Q$qr("T8$44Os   ?9F
r4   rg  )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   	getLoggerri  r  r9   r?   objectr4   r   r:   r8   <module>r     s    " " E E 2 
 + , Q + 6 4 3    $ 4 / ; 5 @ F #      	 g!.& 7<G2Mf Mr:   