)Ej\dZddlmZgdZddlmZddlmZddlm Z ddl m Z erdd lmZm Z d Z d Zd*d Zd*dZdZ d+d,dZ d+ddd-d Zd.d"ZGd#d$eZd/d'Zd*d(Zed)krXdd lZdd lZeejdkrejeejejj d Sd S)0z%Variation fonts interpolation models.) annotations)normalizeValuenormalizeLocation supportScalarpiecewiseLinearMapVariationModel)Mapping) TYPE_CHECKING)noRound)VariationModelError)r Sequencecd|DS)Ncg|]}||SN.0ls IC:\PYTHON\MyICR_Suite\python\Lib\site-packages\fontTools/varLib/models.py znonNone..s , , ,!amAmmmrlsts rnonNoners , ,s , , ,,rc4td|DS)Nc3K|]}|duV dSrrrs r zallNone..s&&&QqDy&&&&&&rallrs rallNoner!s &&#&&& & &&rNctfd|DStfd|DS)Nc3$K|] }|kV dSrr)ritemrefs rrzallEqualTo..!s'//43$;//////rc36K|]}|kVdSrr)rr$mappedmappers rrzallEqualTo..$s066$v%666666rr)r%rr(r's` `@r allEqualTor)s` ~////3////// VC[[F 66666#666 6 66rc|sdSt|} t|}n#t$rYdSwxYwt|||S)NT)r()iternext StopIterationr))rr(itfirsts rallEqualr0'sc t cBR tt eR / / //s % 33czt|t|ksJdt||DS)Ncg|] \}}|| Srr)rrts rrzsubList..4s! / / /$!QQ /A / / /rlenzip)truthrs rsubListr82s; u::S ! ! ! ! / /#c5// / / //rFvfloattripleSequence[float] extrapolateboolreturnc x|\}}}||cxkr|ksntd|dd|dd|d|stt|||}||ks||krdS||kr||ks ||kr||kr ||z ||z z S||kr||ks#||kr||ksJd|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)r9r;r=lowerdefaultuppers rrr7sV#E7E W % % % % % % % % : 9 : :$ 9 : :-2 9 : :    & Au u % %G||u~~s G ((a'kkew>N>NG %00G  0 0 KKEW,,, B B Be B Bw B B% B B B-, G 00r)validatelocationMapping[str, float]axes(Mapping[str, tuple[float, float, float]]rIdict[str, float]c|rt|t|ksKJt|t|z i}|D]6\}}|||d}t |||||<7|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)rJrLr=rIouttagr;r9s rrrXsZ 8==??##s499;;'7'7777X]]__9M9MPS IIKKQ Q : 777 Czz||FF V LLfQi ( (!!VEEEC JrTc|r|tdd}|D]\}\}}} |r8|dkr||ks|| kr |dkr| dkr-||d} n||vsJ||} | |krY|r||\} } | | kr7|| kr1|| kr|| kr|| | z || z z z}| |kr|| |z ||z z z}n<| | kr6| | kr0| |kr||kr|| |z ||z z z}|| kr|| | z || z z z}| |ks| | krd}n&| |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 Nz2axisRanges must be passed when extrapolate is Trueg?rA) TypeErrorrRrS) rJsupportotr= axisRangesscalaraxisrFpeakrHr9axisMinaxisMaxs rrrsDNz)LMMM F&-mmoo(3(3""udE s{{t||te||s{{us{{ T3''AA8####A 99   )$/ GW7{{u//7??te||q5yTE\::Ft^^q5yTE\::F$1E!1!1d??ut||q5yTE\::FG^^q5yTE\::F ::!F E t88 q5yTE\2 2FF q5yTE\2 2FF MrceZdZdZ ddddZdZedZegfdZd Z d Z d Z d Z e d dZe d dZdZdZedZedZdZe d dZe d dZdS)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}] NF)rZcBdDttdDtkrtd_||ng_|_|0|r}ndD}d|D}|_j}t|_ fdD_ fd j D_ i_dS) NcJg|] }d|D!S)c&i|]\}}|dk ||SrArrkr9s r z6VariationModel.__init__...s#???tq!a3hhahhhrrRrlocs rrz+VariationModel.__init__..s/UUUC??syy{{???UUUrc3rK|]2}tt|V3dSr)tuplesortedrRrs rrz*VariationModel.__init__..s:??5 **++??????rzLocations must be unique.c@h|]}|D]}|SrrQrrjr\s r z*VariationModel.__init__.."s-LLLCLL4LLLLrci|]}|dS))r r)rr\s rrgz+VariationModel.__init__..#s@@@dG@@@r) axisOrder)keycDg|]}j|Sr locationsindexrrselfs rrz+VariationModel.__init__..+)CCCA,,Q//CCCrc:g|]}|Srryrrrxs rrz+VariationModel.__init__..,%JJJayq11JJJr)r5rPr origLocationsrtr=computeAxisRangesrZgetMasterLocationsSortKeyFuncrmrxmappingreverseMapping_computeMasterSupports _subModels)r{rxrtr=rZallAxeskeyFuncs`` r__init__zVariationModel.__init__sZVU9UUU s??Y????? @ @C NN R R%&ABB B&&/&;&   A!33I>> LL9LLL@@@@@ $44 5   w777DCCCCCC JJJJ4>JJJ ##%%%rcd|vr||fStd|D}|j|}|?tt ||j|j|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.Nc3K|]}|duV dSrrrr9s rrz-VariationModel.getSubModel..:s&11aATM111111rr=rZ) rlrrSrr8rrtr=rZ)r{rRrusubModels r getSubModelzVariationModel.getSubModel1s u  ; 11511111?&&s++  %T/00 ,? H $,DOC e,,,,rci}d|D}|D][}|D]V}||d}||||f\}}t||t||f||<W\|S)Nc@h|]}|D]}|Srrorps rrqz3VariationModel.computeAxisRanges..Is-DDDCDD4DDDDrr)rSrErD)rxrZrrjr\valuer^r_s rrz VariationModel.computeAxisRangesFs DD9DDD L LC L La((#->>$#G#G #&ug#6#6E78K8K#K 4   LrcLi|vrtdi}|D]|}t|dkrtt|}||}||vrdh||<|||vsJd|d|d||||}d}|||}|S)NzBase master not found.r rAzValue "z" in axisPoints["z"] --> c dfd}|S)Nc&|dkrdn |dkrdndS)Nrrsr r)r9s rsignzJVariationModel.getMasterLocationsSortKeyFunc..getKey..signcs UUrra!ee:rc t}fdD}fdD}|fdtD|t| t fd|Dt |t fd|Dt fd|DfS)Nc6g|]\}}|v ||v|Srr)rr\r axisPointss rrz]VariationModel.getMasterLocationsSortKeyFunc..getKey..key..hsA#ez))ez$7G.G.G.G.G.Grcg|]}|v| Srrrr\rjs rrz]VariationModel.getMasterLocationsSortKeyFunc..getKey..key..msIIITS[[t[[[rcg|]}|v| Srrrr\rts rrz]VariationModel.getMasterLocationsSortKeyFunc..getKey..key..os#RRRdD .getKey..key..tsR 261B1B ---rc3:K|]}|VdSrr)rr\rjrs rrz\VariationModel.getMasterLocationsSortKeyFunc..getKey..key..ys@,0SYrc3BK|]}t|VdSr)absrs rrz\VariationModel.getMasterLocationsSortKeyFunc..getKey..key..|s>+/CIr)r5rRextendrmrQrl)rjrank onPointAxes orderedAxesrtrrs` rruzIVariationModel.getMasterLocationsSortKeyFunc..getKey..keyfsd3xx'*yy{{ JIII III ""RRRRfSXXZZ&8&8RRR%%%$/+&&4?3>rr)rrtrurs`` @rgetKeyz.getKeybs> ; ; ;       6Jr)r r5r,r+add)rxrtrrjr\rrrets rrz,VariationModel.getMasterLocationsSortKeyFuncQs Y  %&>?? ?  ( (C3xx1}}S ??DIE:%%$'5 4 Z-----;@55$$$ S.-- t   ' ' ' '   BfZ++ rcfd|D}fd|D_djDfdD_fdjD_i_|S)Nc g|] }| Srr)ridx master_lists rrz1VariationModel.reorderMasters..s888K$888rc*g|]}j|Sr)r)rrr{s rrz1VariationModel.reorderMasters..s!III#d05IIIrcJg|] }d|D!S)c&i|]\}}|dk ||Srdrres rrgz..s# 6 6 6daQ#XXQXXXrrhris rrz1VariationModel.reorderMasters..s<   ;> 6 6ciikk 6 6 6   rcDg|]}j|Srrwrzs rrz1VariationModel.reorderMasters..r|rc:g|]}|Srr~rs rrz1VariationModel.reorderMasters..rr)rrrxrr)r{rrnew_listrxs`` @rreorderMasterszVariationModel.reorderMasterss9888888IIIIIII  BFBT   DCCCCCC JJJJ4>JJJrcXg|_|}t|D]i\}}t|}|d|D]}t||kr)d}|D]:\}\}} } ||d| ks|||dcxkr| ksnd}n;|s}i} d} |D]g}||d} ||vsJ||\}}} || }}| |kr| }| |z ||z z }n|| kr| }| |z | |z z }nO|| kri} |} || kr|||f| |<h| D] \}}|||< |j|k|dS)NTr Frs)supports_locationsToRegions enumeraterPrQrRappend_computeDeltaWeights)r{regionsiregionlocAxes prev_regionrelevantr\rFr]rHbestAxes bestRatiovallocVnewLowernewUpperratior;s rrz%VariationModel._computeMasterSupportss5 **,,"7++2 )2 )IAv&++--((G&rr{. *. * {''))**g5528,,...D.5$#D)!,44 ;t#4Q#7????%????#( ',,..DDD%d+A.C6>>>>)/&E4).hHTzz#&!$t =#&!$t =!y((#%$)  ))*2D()C$,NN$4$4**LD&#)F4LL* M  ( ( ( ( !!#####rc|j}|j}g}|D]b}i}|D]4\}}|dkrd|||df||< ||d|df||<5||c|S)Nrr )rxrZrRr)r{rxrZrrjrr\rs rrz"VariationModel._locationsToRegionssN _  # #CF!iikk B B d!88$%tZ-=a-@#AF4LL$.t$4Q$7q#AF4LL NN6 " " " "rcg|_t|jD]Z\}}i}t|jd|D]\}}t ||}|r|||<|j|[dSr) deltaWeightsrrxrrr)r{rrj deltaWeightjrXr[s rrz#VariationModel._computeDeltaWeightss// 2 2FAsK' bqb(9:: , , 7&sG44,%+KN   $ $[ 1 1 1 1 2 2rroundct|t|jks+Jt|t|jf|j}g}t|jD]k\}}|||}|D]%\}} | dkr |||z}|||| zz}&|||l|S)Nr )r5rrrrRr) r{ masterValuesrrrTrweightsdeltarweights r getDeltaszVariationModel.getDeltass<  C(9$:$::::    ! " "= :::%#D$566 % %JAw ,E$]]__ - - 6Q;;SVOEESVf_,EE JJuuU|| $ $ $ $ rcn||\}}||||jfS)Nr)rrr)r{rRrmodels rgetDeltasAndSupportsz#VariationModel.getDeltasAndSupportss6''.. uuE22ENBBrc.fdjDS)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().cJg|]}t|jj S)r)rr=rZ)rrXrjr{s rrz-VariationModel.getScalars..sH    W$*:t      r)r)r{rjs``r getScalarszVariationModel.getScalarss8       =     rcT|tttjD]8\}}|D]\}}|xx||zzcc<9fdt tDS)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().c6g|]}j|Sr)r)rrrTr{s rrz3VariationModel.getMasterScalars..s$===s4<?#===r)rreversedlistrrrRranger5)r{targetLocationrrrrrTs` @rgetMasterScalarszVariationModel.getMasterScalarssoon--"4 $2C(D(D#E#EFF * *JAw$]]__ * * 6A#a&6/) *>====U3s88__=== rcd}t|t|ksJt||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(). Nr4)valuesscalarsr9rr[ contributions rinterpolateFromValuesAndScalarsz.VariationModel.interpolateFromValuesAndScalarsst 6{{c'll**** 11 " "ME6  6>Ly \!rc8t||S)z>Interpolate from deltas and scalars fetched from getScalars().)rr)deltasrs rinterpolateFromDeltasAndScalarsz.VariationModel.interpolateFromDeltasAndScalars.s==fgNNNrcX||}|||S)z)Interpolate from deltas, at location loc.)rr)r{rjrrs rinterpolateFromDeltasz$VariationModel.interpolateFromDeltas3s)//#&&33FGDDDrcX||}|||S)z0Interpolate from master-values, at location loc.)rr)r{rjrrrs rinterpolateFromMastersz%VariationModel.interpolateFromMasters8s+'',,33L'JJJrc\|||}|||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)r{rrrrs r interpolateFromMastersAndScalarsz/VariationModel.interpolateFromMastersAndScalars=s/ E::33FGDDDr)NF)__name__ __module__ __qualname____doc__rr staticmethodrrrrrrr rrrrrrrrrrrrrrs//d6;JN<---*\;=222\2h   6$6$6$p    2 2 207"4;CCCCC    "\,OO\OEEE BIKKKKK PWEEEEEEErrrMapping[float, float]c|}|sS|vr|St|}|kr||z|z St|}|kr||z|z Stfd|D}tfd|D}||}||}|||z |z z||z z zS)Nc3(K|] }|k|V dSrrres rrz%piecewiseLinearMap..R' % %!q1uuAuuuu % %rc3(K|] }|k|V dSrrres rrz%piecewiseLinearMap..Srr)rQrErD)r9rrQrfabvavbs` rrrEs <<>>D Dyyqz D A1uu71:~!! D A1uu71:~!! % % % %t % % %%%A % % % %t % % %%%A B B bQU#q1u- --rc ddlm}ddl}|dtj}|dddd |d }|d ddt|ddddd| |}||j ddl m }|j rddl m}|}||j d|jD}t#d|||t#dd|jD}||nJdt't)dt)d d!zD fd"|jD}t-|} t#d#|| jt#d$|| jdS)%z*Normalize locations on a given designspacer) configLoggerNzfonttools varLib.models) descriptionz --loglevelLEVELINFOz Logging level (defaults to INFO))metavarrGhelpT)requiredz-dz --designspace DESIGNSPACE)rtypez-lz --locationsLOCATION+zFMaster locations as comma-separate coordinates. One must be all zeros.)rnargsr)level)pprint)DesignSpaceDocumentcg|] }|j SrrJrss rrzmain..}000q 000rzOriginal locations:zNormalized locations:cg|] }|j Srrrs rrzmain..rrc,g|]}t|Sr)chr)rcs rrzmain..s>>>1A>>>rAZr c g|]<}ttd|dD=S)c34K|]}t|VdSr)r:rs rrz"main...s(;;E!HH;;;;;;r,)dictr6split)rrrLs rrzmain..sQ   BCDT;;aggcll;;;<< = =   rzSorted locations:z Supports:) fontToolsrargparseArgumentParsermainr add_argumentadd_mutually_exclusive_groupstr parse_argsloglevelr  designspacefontTools.designspaceLibr readsourcesprint normalizerordrxrr) argsrrparsergroupr r doclocsrrLs @rr!r!Ysf&&&&&&OOO  $ $!L%F  /   / / / > >E t_m#NNN   U    T " "DLt}%%%%  @@@@@@!!## !"""00CK000 #$$$t   %&&&00CK000t >>c#hhC1 = =>>>    GK~    4 E  F5? + F5>r__main__r)F)r9r:r;r<r=r>r?r:) rJrKrLrMr=r>rIr>r?rN)TFN)r9r:rrr?r:)!r __future__r__all__collections.abcr typingr fontTools.misc.roundToolsr errorsr rrr!r)r0r8rrrobjectrrr!rdoctestsysr5argvexittestmodfailedrrrrAs9++""""""   $##### ------'''''')((((((((---'''77770000000