)EjddZddlTddlmZddlmZddlmZmZm Z ddl m Z ddl m Z mZdd lmZdd lmZmZdd lmZdd lmZdd lmZddlmZddlmZddlmZddl m!Z!m"Z"m#Z#ddl$Z$ddl%Z%e$j&dZ'dZ(dZ)dZ*dZ+GddZ, d"de(e)e+dgddZ-ee-dZ.dZ/dZ0d#d Z1e2d!kr2ddl3Z3e1Z4e3j5e6e7e4dSdS)$z Tool to find wrong contour order between different masters, and other interpolatability (or lack thereof) issues. Call as: $ fonttools varLib.interpolatable font1 font2 ... )*)test_contour_order)test_starting_point) RecordingPenDecomposingRecordingPenlerpRecordings) TransformPen) StatisticsPenStatisticsControlPen)OpenContourError)piecewiseLinearMapnormalizeLocation)floatToFixedToStr) Transform) defaultdict)SimpleNamespace)wraps)pformat)sqrtatan2piNzfontTools.varLib.interpolatablegffffff?g?gMb`?ic,eZdZdZdZdZdZddZdS)Glyph) recordings greenStats controlStats greenVectorscontrolVectors nodeTypes isomorphismspoints openContoursct||_|jD]}t||g||dSN)nameITEMSsetattr _populate)self glyphnameglyphsetitems QC:\PYTHON\MyICR_Suite\python\Lib\site-packages\fontTools/varLib/interpolatable.py__init__zGlyph.__init__4sG J $ $D D$ # # # # x     c|jD]F}tt|||kr#t||dGdSr%)r'lengetattrappend)r*ixr-s r._fill_inzGlyph._fill_in:sYJ 1 1D74&&''2--d##**4000 1 1r0c||j}|du|_|jrdStt|} ||dn%#t $r||YnwxYw|j|_~t|jD]6\}}d|jD}|j |t|}t|} | || ||j dnF#t$r9} |j d||Yd} ~ d} ~ wwxYw|j ||j ||j t)||j t)||ddkr|||ddksJ|d d vsJt-} t/| d} | | |j | jg} |j | t5| j| dt5| j| d8dS) Nr,T)outputImpliedClosingLinecg|]\}}|Sr;).0opargs r. z#Glyph._populate..Ns999C999r0Fr addComponentmoveTo) closePathendPath)r& doesnt_existPerContourOrComponentPenrdraw TypeErrorvaluer enumerater r4r r replayr#r r6rrrcontour_vector_from_statsrSimpleRecordingPointPenSegmentToPointPenr"r!add_isomorphisms) r*r,glyph perContourPenr5contourr rrer" converterr!s r.r)zGlyph._populate?s#!TM    F0QQQ  & JJ}tJ D D D D & & & JJ} % % % % % &'- $T_55( ?( ?KB997=999I N ! !) , , ,&999J/BBBL z***|,,,!((////#   !((... b!!!  O " ": . . .   $ $\ 2 2 2   $ $%>z%J%J K K K   & &'@'N'N O O O|~-- b!!!Q<8++++R=$<<<<<,..F)&%88I NN9 % % % K  v| , , ,L   $ $\ 2 2 2 V\< ? ? ? V\< > > > >Q( ?( ?s*AA10A1'AD,, E/6/E**E/Nc|!|jD]}||dS|j||dSr%)rrG)r*pen contour_idxrRs r.rGz Glyph.drawws[  ? " " S!!!! " " OK ( - -c 2 2 2 2 2r0r%)__name__ __module__ __qualname__r'r/r6r)rGr;r0r.rr's] E!!! 111 6?6?6?p333333r0rF) locations tolerance kinkinessupemshow_all discrete_axesc#lVWXYZ[K|dkr|dz}d|cxkrdksnJ|dkr|dz}d|ksJ|p dD}| dD}t|| \Z} Zfd} |D ]Vtd VVfd D} td | DdkrJt t | |D]`\} \}}}|jr|sVtj|| d fV'd }t |j D]\}}|sd}Vtj || |dfV |r`adgtz}| D ]}| |}||j s| |V}|$| |}||j s6|j }|j Wt|tWkr?Vtj ||||||t|tWdfV|Wkrt t |WD]\}\}}||krt|t|kr@Vtj |||||||t|t|dfVot t ||D]5\}\}}||kr'Vtj||||||||||d fV56t||\} }!| |krQVtj||||||t#t%t|!|!| dfV|!||<|j}"|jX|j}#|jY|j}$|j[||}!|!,Xr*Xfd|!DXYfd|!DY[fd|!D[g}%t |$[D]z\}&}' t-}(t#t/|&j|'j|(_|%|(V#t4$r|%dYwwxYwt t |"XD]\}\})}*|)5|*3t|)dks t|)t|*krAt7|||||!\} }+},| |kr'Vtj|||||||d|+|,| d fV|%|}-|-r|#|ddkY|ddkkrXt;d}.|-|.t?|.}/|#|}0Y|}1|0d|0dz}2|1d|1dz}3|/d|/dz}4t tj tj!fD]\}5}6|5rtE|2|3}7tG|2|3z}7t$d|6|4|7|2|3|5s |7|z|4dzks|5rbd|7|z z|4krV |5r|7|4z } n|4|7z } n#tJ$rd} YnwxYwt$d| V|6|||||||| dfV|j&}|j&W||WrWfd||DWd}8|tNztPz|z }9t t |WD]L\}\})}*|)5|*3t|)dks t|)t|*krAt%t|)D]}:|)|:};|*|:}<|;dr||)|:dzt|)z}?|*|:dzt|*z}@|=dr |>dr|?dr |@drtS|;d};tS|d}>tS|?d}?tS|@d}@|;|=z }A|?|;z }B|<|>z }C|@|zdz }M|?|@zdz }N|L|Mz }O|N|Lz }P|Oj*|Pj+z|Oj+|Pj*zz }Q |QtY|OtY|Pzz}Qn#tJ$rYwxYwtY|Q||zz|8kr|QtY|OztY|Pz}RtY|O|Pz}StY|R|Sz }T|T|9krm|T|Sz }U|U|8krz|8tY|Q|zz } t$d |T|U|Q|Kt$d| Vtj-||||||||:| d!fVN|r"Vtj.||||||d"fV dS)#N g{Gz?rrc,g|]}t|Sr;)repr)r<gs r.r?ztest_gen..s111!d1gg111r0c@h|]}|D]}|Sr;keys)r<r,res r. ztest_gen..s-GGGx}}GG!!GGGGr0)r`c|dS|}|dS|,|||}||||Sr%r;)ir+ glyphsetsparentss r. grand_parentztest_gen..grand_parents` 94 AJ 94aj$1i)@)H Aaj$1i)@)Hr0zTesting glyph %sc0g|]}t|Sr;)r)r<r, glyph_names r.r?ztest_gen..s#KKKXU:x00KKKr0c g|] }|j d S)r)rE)r<rPs r.r?ztest_gen..s CCCe0BCCCCr0)typemaster master_idxFT)rrrsrtrR)rrmaster_1master_2 master_1_idx master_2_idxvalue_1value_2)rrpathrurvrwrxryrz) rrr{noderurvrwrxryrz)rrrurvrwrxryrzr\c g|] }| Sr;r;)r<rkm1Isomorphismss r.r?ztest_gen..9s!F!F!F."3!F!F!Fr0c g|] }| Sr;r;)r<rk m1Vectorss r.r?ztest_gen..:s<<.;s>>>jm>>>r0) rrrRrurvrwrxryrzreversedr\r8z;%s: actual size %g; threshold size %g, master sizes: %g, %ggh㈵>z tolerance %g)rrrRrurvrwrxr\c g|] }| Sr;r;)r<rkm1s r.r?ztest_gen..s666be666r0g?z=kink: deviation %g; deviation_ratio %g; sin_mid %g; r_diff %g)rrrRrurvrwrxrIr\)rrrurvrwrx)/find_parents_and_orderloginfor2rJziprEInterpolatableProblemMISSINGr# OPEN_PATHr PATH_COUNT NODE_COUNTNODE_INCOMPATIBILITYr CONTOUR_ORDERlistranger!rrrr rIr4 ValueErrorrWRONG_START_POINTr rKrL UNDERWEIGHT OVERWEIGHTmaxrdebugZeroDivisionErrorr"DEFAULT_KINKINESS_LENGTHDEFAULT_KINKINESScomplexrealimagabsKINKNOTHING)\rlglyphsnamesignore_missingr[r\r]r^r_r`orderrn allGlyphsrtrPr,r&has_openr5open matchingsm1idxglyph1m0idxglyph0m0pathIxnodes1nodes2nodeIxn1n2this_tolerancematchingm0Isomorphisms m0Vectors recording0 midRecordingc0c1rcontour0contour1proposed_pointreverserRmidStats midVectorm0Vecm1Vecsize0size1midSize overweight problem_type expectedSizetdeviation_thresholdrkpt0pt1pt0_prevpt1_prevpt0_nextpt1_nextd0_prevd0_nextd1_prevd1_nextsin0sin1dot0dot1r0r1r_diffmidmid_prevmid_nextmid_d0mid_d1sin_midcrossarc_len deviationdeviation_ratiorprr~rrmrs\` @@@@@@r.test_genrsBT    Q      BT >>>>  111y111E ~HGIGGG+9MNGU^^  #Z000KKKKKKK CCyCCC D D I I 3<  9e , ,4 4    /J/$! %"$9$A&**4H%e&899  D 5 ?"&&0#%   FS^^+ w w Eu%F~V%5~ L 33E}u%F~V%5~ !B!B2ww#b''!! 5 @$)%L$)%L(-(-#&r77#&r77    Rxx09#b"++0F0F"%"%,F,VV'' 6{{c&kk11&(=(H(.,1%L,1%L0505+.v;;+.v;;      !,5c&&6I6I,J,J%%(R88 *,A,V,2,205e 05e 4949/1/1 !" !" #   %$%,(:&&'I'I $NH )) 5 C$)%L$)%L(-(-#'c(mm(<(<#=#=#+%3      $, % $0N#0N+I+I*J*J!'H$$!F!F!F!FX!F!F!F<<<<8<<< >>>>X>>> Lj*55 . .B.$A">"(BH#E#EFFAG ''****!... ''-----.-6NN33--b b ((Xx$'8}}))8}}H 55:MFB 8;;7"I--"$9$K')(-e (-e ,1,1'('5(/)7  .'r*7 " a 01 4)B-:JQ:NOO,d;;;HNN8,,, 9( C CI%bME%bME!!HuQx/E!!HuQx/E'lYq\9G4=1=1<55++0 L &?+.ue+<++>L Y(#(!! !+/;i/G'TX./X/X(0Y-1L94L-Lw-V-V3#-!L5AG5KNN5<|5KN#4333123IInnEEE *,8/105e 05e 49491?!"!" #    BB++6666Yu%5666A//2CCiO -6c"bkk,B,B| | ((Xx$'8}}))8}}H 55 s8}}--nnA"1+C"1+Cq6!Q! 'AH'AH'Q#h--(?@H'Q#h--(?@H{!x{! {!x{! !3q6*C!3q6*C& 4H& 4H& 4H& 4H"HnG&nG!HnG&nG"<',6 9TTD"<',6 9TTD!G s7|| ;;G s7|| ;;,!!! !4yy1}}D A  #<',6 9TTD"<',6 9TTDaxx4!88 WWG )DEBWWG )DEB b\\F6{{Q 9/C (8 3q8H (8 3q8H 8^F%^F$kFK7&+ :SSG!3v;;V#<<,!!! !7||y9'<=BB $c&kk1CKK?E!&6/22G #EGO 4 4I #666 &/'&9O&** %&#g,,*B%CNIIW!' IInn==="$9$>')(-e (-e ,1,1%&)7       Enh  5 =$)%L$)%L(-(-     ] w O^^sJ;AP  P- ,P-  X X# "X# Ab b- ,b- +"h h h ctt}t|i|D] \}}|||!|Sr%)rrrr4)argskwargsproblemsr+problems r.testrIsQ4  H&777,, 7""7++++ Or0c||vrdS||||<t||dgD]}t|j|||dS)N components)r3recursivelyAddGlyph glyphName)r+r, ttGlyphSetglyf components r.rrQshH$Y/HYT)_lB??MM I/:tLLLLMMr0cttj|}|rtj|d|S)NT)exist_ok)osr{dirnamemakedirs)r{rs r.ensure_parent_dirrZs7good##G, Gd++++ Kr0c 'WXYZ[\ddl}ddl}|dtj}|ddd|d d d |d dt d tz|ddt dtz|dd d|ddd|ddd|ddd|dd d|ddd|dd d|dd td!d"#|d$d%td&d'(|d)d*d d+|d,d d-| |}dd.l m }||j rd/nd01|jr |d21|jr|jnd}dd3lm}g}g}g} t'[t(} t+|j} t/|jd4krd} |jdd5rdd6lm} | |jd} d7| jD|_d8| jD} d9| jD[[fd:| jDZd;| jDYYfd<ZDZn|jdd=rdd>lm }m!}||jd}|j"} ||} d?| jD}d@|D}g|_dA| jD} dB| jDZdC| jDYYfdDZDZn|jddEs!|jddFrddGl#m$}||jd}|dHj%} |dI}iX|jD]}|j&|j'|j(dJX|j)< dK}dL|vr|dL}tU|j+dMdrdNXDXdO}nl|j,D]R\}}X|-}|D]\}}t]||X||<Si}t_t`}dP|vr|dP}|dQ}|&tc|j23}|D]} |j2| D]}!i}"g}#tc|!jD]-\}$}%|%d4|"|$<|#4|$|%d4f.t+|#}&|&|vr|5|"dOdKR||&<tm| ||&||&|ndS|vr|dIj}'|dSj7j8d}(|(j9})|!tc|)3}|D]^} |)| }*|*j:}+tU|+dTdh},tU|+dTd}-d}.|*j;D]?}/|/dUkr|,<|-n|/dTkrt{|.t|sJ|.}-|/}.@t|+dVs|+j@jA}0|,D]}-|0jB|-}1|1jCD]}2|0jDjE|2}3i}"g}#t|3jGD]5\}4}|'|4j)}$|jH}%|%|"|$<|#4|$|%f6t+|#}&|&|vr|5|"dOdKR||&<||&\||&| \| <`dWg}|5g}ig} dXtcX3DZtc|3dYZD]}&d[d\IXfd]|&Dzd[z}5|r|5d^z }5|4|5|4||&| 4ta|&dO|_Jg|_| s d_|D} |jD]}6|6d`rQddalKmL}7|7|6}t}8|N|8|8j%} |4|n3ddGl#m$}||6}|dHj%} |4||4||6Odbd4dt/|dckrtQdddSg}|D]\}t|der|5\n|\|4\fdf\3D]|jRrZt'|jRWWfdgt||D}Wfdht|| D} Wfdi|D}|s&tct'dj|D}t'|}9|D]4\t'\3}:|9|:z };|;r |;D]} tVdlt/|tVdmt| t|||| | |jJ|=|>|jY[n }?t_t}@|j[|j\n!tt|j[do}A|j_s|j`rMddl`}B|?D] \} }C|@| 4|C!t|Bb|@|Apnd}D|?D]\} }E|@| 4|E| |Dkrtdq| dr|Ap| }Dd}Fds|Evr |Edsfn|Edt|Eduf}G|G|FkrFdv|Evr |Edvfn|Edw|Edxf}HtdydzI|Hz|Ap|G}F|Ed{tjdkrtd||Edvz|Ap|Ed{tjekrtd}|Edvz|Ap |Ed{tjfkr2td~|Ed|Edw|Ed|Edxfz|ApT|Ed{tjgkr9td|Ed|Ed|Edw|Ed|Edxfz|Ap|Ed{tjhkr@td|Ed|Ed|Ed|Edw|Ed|Edxfz|Ap|Ed{tjikr7td|Edd|Edwdz|Edd|Edx|ApF|Ed{tjjkr@td|Ed|Ed|Edw|Ed|Edx|Edfz|Ap|Ed{tjkkr+td|Ed|Edw|Edxfz|Ap|Ed{tjlkr+td|Ed|Edw|Edxfz|Ap|Ed{tjmkr2td|Ed|Ed|Edw|Edxfz|Apf|Ed{tjnkr#td|Edwd|Edx|Apn#|?D] \} }C|@| 4|C!t|@}@dD]}EtU||E}I|ItVd|Ep|Id4dlqmr}Jms}K|Edkr|Jn|K}L|Lt|I||5}M|Mt| |=|>|@r|Mu|@|Mv|@|@s|j_s|Mw|@r(|Mx|Mydddn #1swxYwY|jzr#tVd|jzd4dlqm{}Ng}Oi}P|N|O||5}Q|Qt| dK|=|>|@D]1\}R}S|R|Pt/|O<|Qv|R|SidKdK2|@s|j_s|Qwdddn #1swxYwYddl|}Ttt|jzd5}A|A}d|A}d|A}dt|OD]\}U}Q|U|Pvr2|A}d|P|Ud~d|A}d~d|A}|T|Q|A}d|A}d|A}ddddn #1swxYwYn>#t$r0}V|Vxj| z c_t|Vd}V~VwwxYw|@r|@SdS)z/Test for interpolatability issues between fontsrNzfonttools varLib.interpolatable) descriptionz--glyphsstorez&Space-separate name of glyphs to check)actionhelpz --show-all store_truez3Show all glyph pairs, even if no problems are foundz --tolerancez,Error tolerance. Between 0 and 1. Default %s)rrrrz --kinkinessz)How aggressively report kinks. Default %sz--jsonzOutput report in JSON formatz--pdfzOutput report in PDF formatz--psz"Output report in PostScript formatz--htmlzOutput report in HTML formatz--quietz%Only exit with code 1 or 0, no outputz--outputz3Output file for the problem report; Default: stdoutz--ignore-missingz.sIII66;IIIr0cg|] }|j Sr;locationrs r.r?zmain..KKKVKKKr0c<h|]}t|d|jS)minimum)hasattrr&r<as r.rizmain..s998M8Mr0cVi|]%}|jv |j|j|j|jf&Sr;r&rdefaultmaximum)r<rr`s r. zmain..sA6..AIqy9...r0c(i|]}|j|jSr;r&maprs r.r zmain..EEEqQVQUEEEr0cRi|]"\}tfd|D#S)c3^K|]'}t|tV(dSr%rdictr<v axis_mappingsks r. z"main...;SS1+AtM!4D/E/EFFSSSSSSr0tupler<vvr,r+s @r.r zmain..QAr5SSSSSPRSSSSSr0)z.glyphsz.glyphspackage)GSFontto_designspacecg|] }|j Sr;)font)r<sources r.r?zmain..sCCCVV[CCCr0cDg|]}|jjd|jjS)-)r familyName styleName)r<fs r.r?zmain..s0TTT 1 1 1163C3CDTTTr0cg|] }|j Sr;rrs r.r?zmain..rr0cBi|]}|j|j|j|jfSr;rrs r.r zmain..s6>?AIqy9r0c(i|]}|j|jSr;r"rs r.r zmain..r$r0cRi|]"\}tfd|D#S)c3^K|]'}t|tV(dSr%r'r)s r.r-z"main...r.r0r/r1s @r.r zmain..r3r0z.ttfz.otf)TTFontheadfvarrBrrFavarVarStoreci|] }|dddd S)rBrrrFr;)r<tags r.r zmain..s$"T"T"T3RA!(<(<"T"T"Tr0Tgvarr)r normalized recalcBoundsCFF2vsindexblendvstorez''ci|]}|dS)rFr;rs r.r zmain..dsOOOqA{OOOr0c$t||fSr%)r2)r*s r.zmain..esCFFA;r0)key' c 3pK|]0\}}|dtt||dV1dS)=N)rr)r<r,r* axisMappings r.r-zmain..hsk  !Aq AA- 21k!n E Er      r0z (normalized)cg|]}iSr;r;)r<_s r.r?zmain..~s'''AR'''r0z.ufo) UFOReader.rz9Font file does not seem to be variable. Nothing to check. getGlyphSetc"i|] }|| Sr;r;)r<r,r,s r.r zmain..sBBBQ!Xa[BBBr0c"g|] \}}|v | Sr;r;)r<r&r,accepted_namess r.r?zmain..2   h~%% %%%r0c"g|] \}}|v | Sr;r;)r<r&rrcs r.r?zmain..rdr0cg|]}|v| Sr;r;)r<r&rcs r.r?zmain..s#BBB$4>+A+A+A+A+Ar0c@g|]}|D]}|Sr;rg)r<r,gns r.r?zmain..s-TTTHHMMOOTTbRTTTTr0ctg|]4}it|fd|D5S)c$i|] \}}|v || Sr;r;)r<r,r*r`s r.r z#main...s)BBB1qM/A/Aq!/A/A/Ar0)ritems)r<loc axis_triplesr`s r.r?zmain..sa   \22 BBBB BBB r0zRunning on %d glyphsetsz Locations: %s) rrr[r^rr\r]r_r`w)filezGlyph z was not compatible:rtrwrxrsrurvz Masters: %s:z, rrz" Glyph was missing in master %sz' Glyph has an open path in master %sz* Path count differs: %i in %s, %i in %sryrzz5 Node count differs in path %i: %i in %s, %i in %sr{z7 Node %d incompatible in path %i: %s in %s, %s in %sr|z Contour order differs: z in zD Contour %d start point differs: %s in %s, %s in %s; reversed: %srRrz3 Contour %d interpolation is underweight: %s, %sz2 Contour %d interpolation is overweight: %s, %sz' Contour %d has a kink at %s: %s, %srIz Showing z and )pspdfzWriting %s to %s)InterpolatablePSInterpolatablePDFrp)rlr)r\r]zWriting HTML to %s)InterpolatableSVG)show_tolerancer\r])rushow_page_numberwbs sN s6fonttools varLib.interpolatable report z

Glyph z

zutf-8z$ s
s )argparsesysArgumentParsermain__doc__ add_argumentfloatDEFAULT_TOLERANCErstr parse_args fontToolsr verboserrsplitos.pathrset DEFAULT_UPEMr0rr2endswithfontTools.designspaceLibrfromfilesourcesaxesrk glyphsLibr4r5upmfontTools.ttLibrC unitsPerEmminValue defaultValuemaxValueaxisTagr3tablesegmentscopyrrr(sorted variationsrhr4r`rcff topDictIndex CharStringsprivateprogramadd isinstanceintrrQ otVarStoreVarDataVarRegionIndex VarRegionListRegionrJ VarRegionAxis PeakCoordjoinrfontTools.ufoLibr^rreadInforsplitrwarningr&rr\r]rrrr_routputstdoutrrquietjsonprintdumpsrrrrrrrrrrrr sort_problemsupperinterpolatablePlotrrrsadd_title_page add_summary add_problems draw_cupcake add_indexadd_table_of_contentshtmlrtbase64writeencode b64encode Exceptionrerror)]rrxryparserr rrfontsrr[r^original_args_inputs designspacerr4r5gsfontrCr7rEaxisrLrGrr fvarMappingrrI ttGlyphSetsrlrKrr+varlocDictrlrJvallocTuplefvarAxescff2 charstringscsr vsindicesrOlast_opr=varStorevarData regionIndexregion axisIndexr&filenamer^r glyphsSetglyphSetGlyphNamesdiffrhr\r] problems_genrr=rrlast_glyphnameplast_master_idxs master_idxs master_namesr>rrrs PlotterClassdocrtsvgs glyph_startssvgrPglyph_problemsrrkrSrcr[r+rmr`r,s] @@@@@@r.r{r{asOOOJJJ  $ $)L%F  5   B    ;>O O     8;L L    +   *   1   +   4   B   K    b    V  k,EUVVV  ,=UVVV   T " "D&&&&&&L$,=I???? z$ 7####$(K 9T[   TF      E EIEEM D -- 4;1 ;q> " "> 2 2q  D D D D D D-66t{1~FFKII[5HIIIDKKK{7JKKKI + 0M$)L FEK4DEEEM)//11LL [^ $ $%B C C]  8 8 8 8 8 8 8 8VDKN++F:D(.00KCC{/BCCCETTeTTTEDKKK{7JKKKICNCSLFEK4DEEEM)//11LL [^ $ $V , ,J  A0G0G0O0OJ  . . . . . .6$+a.))D<*D#DO$8$8$:$:;;F!'I#y9"$ (.sx~~/?/?(@(@66HC+.q6GCLJJSV}5555#(::#;66484D4D)0TPU5E55K1,%y':K#K$4$4$6$677F!'-S-SI$Y/B jG"))Q!?!? @I%gy!<>#3#39N9NOOO 1 1hh    %-       ,O+D T""" Yx0111  h0000"&D DK (''''' K;;   V $ $  2 2 2 2 2 29X&&D"$$D MM$   ?D LL     . . . . . .6(##D<*D LL    XXh''..sA66q9:::: 5zzA~~ OPPPIDD 4 ' ' ''))HHHBBBB(--//BBBCCCC y CTY    "%eY"7"7       "%eY"7"7   CBBB%BBB WTT TTTUUVVF I$$ 11--  $ $ $#   I3"3I"&."<BSIm *C NN;;; ')"4"4555 .]'    t$${" JJ' 44c:: zO 4yK  *688&IwY'..w7777djj**33333!%$0BBLIqY'..q111 N22FyFFFQOOOO)2+/((1,,<**/>1BC #&666 (1}}x[NN"#J-:!?% /$))L2I2IIPQRRRR+6(y$9$AAA@1X;NUV6&;&EEEE( S!"6&;&FFFH !) !* !) !* "#     6&;&FFFS !& !) !* !) !* "#     6&;&PPPU !& !& !) !* !) !* "#     6&;&III!") !* !) !* "#     6&;&MMMb !) !) !* !) !* !* "#     6&;&GGGQ !) !* !*  "#6&;&FFFP !) !* !*  "#6&;&@@@E !) !' !* !* "#     6&;&CCC!"* !*  "# wBH'3 4 4" 7#**73333 ** 0 0A$""C{ HH'C 8 8 8 O O O O O O O O/0Dyy++>OL!#&&)5 0""(I#.OOH---  ***' '$$&&&0MMOOO--/// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9& - HH)49 5 5 5 = = = = = =DL""49EJJJ 'c""(#('' # .6^^-=-=)E>.3LT+$$/',).%  ' '$$&&& ' ' ' ' ' ' ' ' ' ' ' ' ' ' '" MMM' 22D99 -Q,---fRSSS'oo''FAsL(( E\!_ E E E L LW U UVVVGGBII'RRSSSGGF,,S11222GGI&&&GGI&&&&+,,, - - - - - - - - - - - - - - -  && !   s8UAN'CB AE.E" AN'E.AE2 E2AN'E5AE2 E6AAN'F;A=AIH8 AN'IAIIAN'I AII )AN'I5DANN AN'NANNAN'N"ANN#AN'N' AO"N2+AOOAO"__main__)NNFr%)8r|interpolatableHelpersinterpolatableTestContourOrderrinterpolatableTestStartingPointrfontTools.pens.recordingPenrrr fontTools.pens.transformPenr fontTools.pens.statisticsPenr r fontTools.pens.momentsPenr fontTools.varLib.modelsrrfontTools.misc.fixedToolsrfontTools.misc.transformr collectionsrtypesr functoolsrpprintrmathrrrloggingr getLoggerrrrrrrrrrrr{rXryrexitrboolr;r0r.rs%$$$>>>>>>@@@@@@ 544444LLLLLLLL666666IIIIIIII777777......######!!!!!!  g9::  U3U3U3U3U3U3U3U3t   G   GGGGGTxMMMQ Q Q Q h zJJJtvvH CHSSh !!!!! r0