L i~WVdZgdZddlmZddlmZdZdZdd Zdd Z d Z dd Z dd ddZ ddZ GddeZdZddZedk(r`ddlZddlZeej,dkDrej.eej.ej0j2yy)z%Variation fonts interpolation models.)normalizeValuenormalizeLocation supportScalarpiecewiseLinearMapVariationModel)noRound)VariationModelErrorc2|Dcgc]}|| c}Scc}wN)lstls ]/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/fontTools/varLib/models.pynonNoners ,!amA ,, ,sc&td|DS)Nc3$K|]}|du ywr r .0rs r zallNone..s&QqDy&all)rs rallNoners &#& &&Ncntfd|DStfd|DS)Nc3(K|] }|k( ywr r )ritemrefs rrzallEqualTo..s/43$;/sc34K|]}|k(ywr r )rrmappedmappers rrzallEqualTo..s6$v%6r)rrr"r!s` `@r allEqualTor$s3 ~/3/// C[F 6#6 66rcp|syt|} t|}t|||S#t$rYywxYw)NT)r")iternext StopIterationr$)rr"itfirsts rallEqualr+sD  cBR eR // s ) 55ct|t|k(sJt||Dcgc] \}}|s | c}}Scc}}wr lenzip)truthrrts rsubListr2*s8 u:S !! !c5/ /$!QQA // /s <<Fc @|\}}}||cxkr|ksntd|dd|dd|d|stt|||}||k(s||k(ry||kr||k7s ||kDr||k(r ||z ||z z S||kDr||k7s||kr||k(sJd|d|d|d|d ||z ||z z S)zNormalizes value based on a min/default/max triple. >>> normalizeValue(400, (100, 400, 900)) 0.0 >>> normalizeValue(100, (100, 400, 900)) -1.0 >>> normalizeValue(650, (100, 400, 900)) 0.5 z8Invalid axis values, must be minimum, default, maximum: z3.3fz, z Ooops... v=z , triple=()) ValueErrormaxmin)vtriple extrapolatelowerdefaultuppers rrr/s#E7E W % %FTl"WTN"U4L :    Au u %G|u~ G (a'kew>NG %00G  0 KEW, C :eWBwir% B C G 00r)validatec`|rkt|jt|jks8Jt|jt|jz i}|jD]+\}}|j||d}t |||||<-|S)aNormalizes location based on axis min/default/max values from axes. >>> axes = {"wght": (100, 400, 900)} >>> normalizeLocation({"wght": 400}, axes) {'wght': 0.0} >>> normalizeLocation({"wght": 100}, axes) {'wght': -1.0} >>> normalizeLocation({"wght": 900}, axes) {'wght': 1.0} >>> normalizeLocation({"wght": 650}, axes) {'wght': 0.5} >>> normalizeLocation({"wght": 1000}, axes) {'wght': 1.0} >>> normalizeLocation({"wght": 0}, axes) {'wght': -1.0} >>> axes = {"wght": (0, 0, 1000)} >>> normalizeLocation({"wght": 0}, axes) {'wght': 0.0} >>> normalizeLocation({"wght": -1}, axes) {'wght': 0.0} >>> normalizeLocation({"wght": 1000}, axes) {'wght': 1.0} >>> normalizeLocation({"wght": 500}, axes) {'wght': 0.5} >>> normalizeLocation({"wght": 1001}, axes) {'wght': 1.0} >>> axes = {"wght": (0, 1000, 1000)} >>> normalizeLocation({"wght": 0}, axes) {'wght': -1.0} >>> normalizeLocation({"wght": -1}, axes) {'wght': -1.0} >>> normalizeLocation({"wght": 500}, axes) {'wght': -0.5} >>> normalizeLocation({"wght": 1000}, axes) {'wght': 0.0} >>> normalizeLocation({"wght": 1001}, axes) {'wght': 0.0} r )r;)setkeysitemsgetr)locationaxesr;r?outtagr:r9s rrrNsN8==?#s499;'77 X]]_9MPS IIKQ :  7 Czz|F V LLfQi (!!VECF Jrc6|r | tdd}|jD]\}\}}} |r/|dk(r||kDs|| kDr|dkr| dkDr(|j|d} n ||vsJ||} | |k(rL|rv||\} } | | kr2|| kr-|| kr|| kr|| | z || z z z}y| |krF|| |z ||z z z}| | kr2| | kr-| |kr||kr|| |z ||z z z}|| kr|| | z || z z z}| |ks| | krd}|S| |kr|| |z ||z z z}|| | z || z z z}|S)aReturns the scalar multiplier at location, for a master with support. If ot is True, then a peak value of zero for support of an axis means "axis does not participate". That is how OpenType Variation Font technology works. If extrapolate is True, axisRanges must be a dict that maps axis names to (axisMin, axisMax) tuples. >>> supportScalar({}, {}) 1.0 >>> supportScalar({'wght':.2}, {}) 1.0 >>> supportScalar({'wght':.2}, {'wght':(0,2,3)}) 0.1 >>> supportScalar({'wght':2.5}, {'wght':(0,2,4)}) 0.75 >>> supportScalar({'wght':2.5, 'wdth':0}, {'wght':(0,2,4), 'wdth':(-1,0,+1)}) 0.75 >>> supportScalar({'wght':2.5, 'wdth':.5}, {'wght':(0,2,4), 'wdth':(-1,0,+1)}, ot=False) 0.375 >>> supportScalar({'wght':2.5, 'wdth':0}, {'wght':(0,2,4), 'wdth':(-1,0,+1)}) 0.75 >>> supportScalar({'wght':2.5, 'wdth':.5}, {'wght':(0,2,4), 'wdth':(-1,0,+1)}) 0.75 >>> supportScalar({'wght':3}, {'wght':(0,1,2)}, extrapolate=True, axisRanges={'wght':(0, 2)}) -1.0 >>> supportScalar({'wght':-1}, {'wght':(0,1,2)}, extrapolate=True, axisRanges={'wght':(0, 2)}) -1.0 >>> supportScalar({'wght':3}, {'wght':(0,2,2)}, extrapolate=True, axisRanges={'wght':(0, 2)}) 1.5 >>> supportScalar({'wght':-1}, {'wght':(0,2,2)}, extrapolate=True, axisRanges={'wght':(0, 2)}) -0.5 z2axisRanges must be passed when extrapolate is Trueg?r4) TypeErrorrCrD) rEsupportotr; axisRangesscalaraxisr<peakr>r9axisMinaxisMaxs rrrsDz)LMM F&-mmo(3""udE s{t|te|s{us{ T3'A8# ##A 9  )$/ GW7{u/7?te|q5yTE\::Ft^q5yTE\::F1E!1d?ut|q5yTE\::FG^q5yTE\::F :!F  M t8 q5yTE\2 2F q5yTE\2 2FQ(3R MrceZdZdZ ddddZdZedZegfdZdZ d Z d Z d Z e d d Ze d dZdZdZedZedZdZe d dZe d dZy)ra5Locations must have the base master at the origin (ie. 0). If axis-ranges are not provided, values are assumed to be normalized to the range [-1, 1]. If the extrapolate argument is set to True, then values are extrapolated outside the axis range. >>> from pprint import pprint >>> axisRanges = {'wght': (-180, +180), 'wdth': (-1, +1)} >>> locations = [ {'wght':100}, {'wght':-100}, {'wght':-180}, {'wdth':+.3}, {'wght':+120,'wdth':.3}, {'wght':+120,'wdth':.2}, {}, {'wght':+180,'wdth':.3}, {'wght':+180}, ] >>> model = VariationModel(locations, axisOrder=['wght'], axisRanges=axisRanges) >>> pprint(model.locations) [{}, {'wght': -100}, {'wght': -180}, {'wght': 100}, {'wght': 180}, {'wdth': 0.3}, {'wdth': 0.3, 'wght': 180}, {'wdth': 0.3, 'wght': 120}, {'wdth': 0.2, 'wght': 120}] >>> pprint(model.deltaWeights) [{}, {0: 1.0}, {0: 1.0}, {0: 1.0}, {0: 1.0}, {0: 1.0}, {0: 1.0, 4: 1.0, 5: 1.0}, {0: 1.0, 3: 0.75, 4: 0.25, 5: 1.0, 6: 0.6666666666666666}, {0: 1.0, 3: 0.75, 4: 0.25, 5: 0.6666666666666667, 6: 0.4444444444444445, 7: 0.6666666666666667}] N)rMc >ttd|Dt|k7r td||_||ng|_||_|J|r|j |}n6|Dchc]}|jD]}|}}}|Dcic]}|d}}||_|D cgc],}|jD cic]\}} | dk7s || c} }.}}}} |j||j} t|| |_ |D cgc]} |jj| c} |_|jD cgc]} |j| c} |_|j!i|_ycc}}wcc}wcc} }wcc} }}wcc} wcc} w)Nc3`K|]&}tt|j(ywr )tuplesortedrCrs rrz*VariationModel.__init__..s ?5 *+?s,.zLocations must be unique.)r r4) axisOrder)key)r.rAr origLocationsrYr;computeAxisRangesrBrMrCgetMasterLocationsSortKeyFuncrW locationsindexmappingreverseMapping_computeMasterSupports _subModels) selfr^rYr;rMlocrOallAxeskr9keyFuncrs r__init__zVariationModel.__init__s{ s?Y?? @C N R%&AB B&&/&;&  !33I> +4LCL4L4LL8?@dGm@ @$KTUUCsyy{?tq!a3had?U U44 5  w7:CCA,,Q/C ;?>>Jayq1J ##%M@@UDJs6'E= F%F= F FF "FFFcd|vr||fStd|D}|jj|}|9tt ||j |j }||j|<|t ||fS)zReturn a sub-model and the items that are not None. The sub-model is necessary for working with the subset of items when some are None. The sub-model is cached.Nc3$K|]}|du ywr r rr9s rrz-VariationModel.getSubModel..*s1aATM1r)rVrcrDrr2r[rY)rdrCrZsubModels r getSubModelzVariationModel.getSubModel!s} u ; 1511??&&s+  %gc43E3E&FWH#+DOOC e,,,rci}|Dchc]}|jD]}|}}}|D]M}|D]F}|j|d}|j|||f\}}t||t||f||<HO|Scc}}w)Nr)rBrDr8r7)r^rMrerOrfvaluerQrRs rr\z VariationModel.computeAxisRanges1s #,DCD4D4DD LC La(#->>$#G #&ug#6E78K#K 4  L L  EsA=ci|vr tdi}|D]_}t|dk7rtt|}||}||vrdh||<|||vsJd|d|d|||j |ad}|||}|S)NzBase master not found.r r4zValue "z" in axisPoints["z"] --> c dfd}|S)Nc"|dkrdS|dkDrdSdS)NrrXr r )r9s rsignzJVariationModel.getMasterLocationsSortKeyFunc..getKey..signNsUr:a!e::rc t}jDcgc]\}}|vr ||vr|}}}Dcgc] }|vs| }}|jtj Dcgc] }|vs| c}|t| t fd|Dt |t fd|Dt fd|DfScc}}wcc}wcc}w)Nc3LK|]}|vrj|ndyw)iN)r_)rrOrYs rrz\VariationModel.getMasterLocationsSortKeyFunc..getKey..key.._s. 261B -Os!$c34K|]}|ywr r )rrOrerts rrz\VariationModel.getMasterLocationsSortKeyFunc..getKey..key..ds,0SYr#c3:K|]}t|ywr )abs)rrOres rrz\VariationModel.getMasterLocationsSortKeyFunc..getKey..key..gs+/CIs)r.rCextendrWrBrV) rerankrOrp onPointAxes orderedAxesrY axisPointsrts ` rrZzIVariationModel.getMasterLocationsSortKeyFunc..getKey..keyQs3x(+yy{#ez)ez$7G.G  1:ITS[tI I""&,SXXZ&8RdD  JRsC C" C"5 C'?C'r )r~rYrZrts`` @rgetKeyz.getKeyMs ; 6Jr)r r.r'r&add)r^rYr~rerOrprrets rr]z,VariationModel.getMasterLocationsSortKeyFunc<s Y %&>? ?  (C3x1}S ?DIE:%$'5 4 Z-- T;@$ S T- t   ' ( BZ+ rc |Dcgc]}|| }}|Dcgc]}|j|c}|_|jDcgc],}|jDcic]\}}|dk7s ||c}}.}}}}|D cgc]} |jj| c} |_|jD cgc]} |j| c} |_i|_|Scc}wcc}wcc}}wcc}}}wcc} wcc} w)Nr4)r[rCr^r_r`rarc) rd master_listr`idxnew_listrergr9r^rs rreorderMasterszVariationModel.reorderMastersqs188K$88AHI#d005IBFBTBT  ;>ciik 6daQ#XQT 6  :CCA,,Q/C ;?>>Jayq1J9I 6 DJs4 CC$C/ C)+C)0C/>"C66C;)C/cg|_|j}t|D]4\}}t|j }|d|D]}t|j |k7r d}|j D],\}\}} } ||d| k(r|||dcxkr| kr(nd}n|sdi} d} |j D][}||d} ||vsJ||\}}} || }}| |kr| }| |z ||z z }n|| kr| }| |z | |z z }nE|| kDri} |} || k(sT|||f| |<]| j D] \}}|||< |jj |7|jy)NTr FrX)supports_locationsToRegions enumeraterArBrCappend_computeDeltaWeights)rdregionsiregionlocAxes prev_regionrelevantrOr<rPr>bestAxes bestRatiovallocVnewLowernewUpperratior:s rrbz%VariationModel._computeMasterSupports~s **,"7+2 )IAv&++-(G&r{. * {'')*g528,,..D.5$#D)!,4 ;t#4Q#7?%?#(   ',,.DD%d+A.C6>)>)/&E4).hHTz#&!$t =#&!$t =!y(#%$)  )*2D()C%D(%-NN$4*LD&#)F4L*[. *^ MM  (e2 )f !!#rc|j}|j}g}|D]O}i}|jD]'\}}|dkDrd|||df||<||d|df||<)|j|Q|S)Nrr )r^rMrCr)rdr^rMrrerrOrs rrz"VariationModel._locationsToRegionssNN __  #CF!iik B d!8$%tZ-=a-@#AF4L$.t$4Q$7q#AF4L  B NN6 " #rcg|_t|jD]V\}}i}t|jd|D]\}}t ||}|s|||<|jj |Xyr ) deltaWeightsrr^rrr)rdrre deltaWeightjrKrNs rrz#VariationModel._computeDeltaWeightss|/ 2FAsK' bq(9: , 7&sG4%+KN ,    $ $[ 1 2rroundct|t|jk(s%Jt|t|jf|j}g}t|jD]U\}}|||}|j D]\}} | dk(r |||z}|||| zz} |j ||W|S)Nr )r.rrarrCr) rd masterValuesrr`rGrweightsdeltarweights r getDeltaszVariationModel.getDeltass< C(9(9$::   !! "=  :%%#D$5$56 %JAw ,E$]]_ - 6Q;SVOESVf_,E  - JJuU| $ % rch|j|\}}|j|||jfS)Nr)rnrr)rdrCrmodels rgetDeltasAndSupportsz#VariationModel.getDeltasAndSupportss2''. uuE2ENNBBrc |jDcgc]%}t|||j|j'c}Scc}w)zReturn scalars for each delta, for the given location. If interpolating many master-values at the same location, this function allows speed up by fetching the scalars once and using them with interpolateFromMastersAndScalars().)r;rM)rrr;rM)rdrerKs r getScalarszVariationModel.getScalarssB ==   W$*:*:t    s*<cH|j|}ttt|jD]0\}}|j D]\}}||xx|||zzcc<2t t|Dcgc]}||j|}}|Scc}w)aReturn multipliers for each master, for the given location. If interpolating many master-values at the same location, this function allows speed up by fetching the scalars once and using them with interpolateFromValuesAndScalars(). Note that the scalars used in interpolateFromMastersAndScalars(), are *not* the same as the ones returned here. They are the result of getScalars().) rreversedlistrrrCranger.r`)rdtargetLocationrGrrrrs rgetMasterScalarszVariationModel.getMasterScalarssoon-"4 $2C2C(D#EF *JAw$]]_ * 6A#a&6/) * *.33s8_=s4<<?#== >sBcd}t|t|k(sJt||D]\}}|s ||z}||}||z }|S)aVInterpolate from values and scalars coefficients. If the values are master-values, then the scalars should be fetched from getMasterScalars(). If the values are deltas, then the scalars should be fetched from getScalars(); in which case this is the same as interpolateFromDeltasAndScalars(). Nr-)valuesscalarsr9rprN contributions rinterpolateFromValuesAndScalarsz.VariationModel.interpolateFromValuesAndScalarssc 6{c'l*** 1 "ME6 6>Ly \! "rc.tj||S)z>Interpolate from deltas and scalars fetched from getScalars().)rr)deltasrs rinterpolateFromDeltasAndScalarsz.VariationModel.interpolateFromDeltasAndScalarss==fgNNrcH|j|}|j||S)z)Interpolate from deltas, at location loc.)rr)rdrerrs rinterpolateFromDeltasz$VariationModel.interpolateFromDeltass#//#&33FGDDrcH|j|}|j||S)z0Interpolate from master-values, at location loc.)rr)rdrerrrs rinterpolateFromMastersz%VariationModel.interpolateFromMasters#s%'',33L'JJrcL|j||}|j||S)zInterpolate from master-values, and scalars fetched from getScalars(), which is useful when you want to interpolate multiple master-values with the same location.r)rr)rdrrrrs r interpolateFromMastersAndScalarsz/VariationModel.interpolateFromMastersAndScalars(s) E:33FGDDr)NF)__name__ __module__ __qualname____doc__rirn staticmethodr\r]rrbrrrrrrrrrrrrr rrrrs/d6;JN<- ;=22h 6$p  207"4;C  ",OOE BIK PWErrc6|j}|sS|vr|St|}|kr ||z|z St|}|kDr ||z|z Stfd|D}tfd|D}||}||}|||z |z z||z z zS)Nc3.K|] }|ks |ywr r rrgr9s rrz%piecewiseLinearMap..= %!q1uA % c3.K|] }|kDs |ywr r rs rrz%piecewiseLinearMap..>rr)rBr8r7)r9r`rBrgabvavbs` rrr0s <<>D Dyqz D A1u71:~!! D A1u71:~!! %t %%A %t %%A B B bQU#q1u- --rc `ddlm}ddl}|jdtj }|j dddd |jd }|j d ddt|j ddddd|j|}||jddl m }|jrddl m}|}|j|j|j Dcgc]}|j"} }t%d|| |j't%d|j Dcgc]}|j"} }|| nyt)t+dt+ddzD cgc] } t-| } } |j.Dcgc]-}t1t3| d|j5d D/} }t7| } t%d!|| j.t%d"|| j8ycc}wcc}wcc} wcc}w)#z*Normalize locations on a given designspacer) configLoggerNzfonttools varLib.models) descriptionz --loglevelLEVELINFOz Logging level (defaults to INFO))metavarr=helpT)requiredz-dz --designspace DESIGNSPACE)rtypez-lz --locationsLOCATION+zFMaster locations as comma-separate coordinates. One must be all zeros.)rnargsr)level)pprint)DesignSpaceDocumentzOriginal locations:zNormalized locations:AZr c32K|]}t|ywr )floatrls rrzmain..rs;E!H;s,zSorted locations:z Supports:) fontToolsrargparseArgumentParsermainr add_argumentadd_mutually_exclusive_groupstr parse_argsloglevelr designspacefontTools.designspaceLibrreadsourcesrEprint normalizerordchrr^dictr/splitrr) argsrrparsergrouprrdocslocscrFrs rrrDs&  $ $!LL%F  /   / / / >E t_m#N   U    T "Dt}}% @!# !!"$'KK0q 00 #$t   %&$'KK0q 00t %c#hC1 =>1A>>GK~~ BCDT;aggcl;< =   4 E  5?? + 5>>#1 1? s.H?H!H&"2H+__main__r )F)TFN)r__all__fontTools.misc.roundToolsrerrorsr rrr$r+r2rrrobjectrrrrdoctestsysr.argvexittestmodfailedr rrr s+ .'-'700 1>/U/dNb\EV\E~ .(5p z 388}q CHH_W__  % %& r