
    jkej                         d dl mZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZ d dlZd dlZd d	lmZ g d
Z ej*                  d      Zg dZg dZ ed  edd      D              Zg dZdZd Zd Zd Z d Z!d Z"d(dZ#d(dZ$d(dZ%d Z&d Z'd Z(	 	 	 	 	 d)dZ)	 	 	 	 	 	 d*dZ*	 	 	 	 	 	 d*d Z+	 	 	 	 	 	 d*d!Z,	 	 	 	 	 	 d*d"Z-d# Z.d$ Z/	 	 	 	 	 	 d+d%Z0d(d&Z1e2d'k(  rd dl3Z3 e3jh                   e1              yy),    )newTable)Axis)AreaPen)NullPen)StatisticsPen)piecewiseLinearMapnormalizeValue)makeOutputFileNameN)pformat)planWeightAxisplanWidthAxisplanSlantAxisplanOpticalSizeAxisplanAxissanitizeWeightsanitizeWidthsanitizeSlantmeasureWeightmeasureWidthmeasureSlantnormalizeLinearnormalizeLognormalizeDegreesinterpolateLinearinterpolateLogprocessAxismakeDesignspaceSnippetaddEmptyAvarmainzfontTools.varLib.avarPlanner)2   d            i,  i^  i  i  i  i&  iX  i  i  i  i   iR  i  i  )g      9@g     B@g      I@g     @O@g     R@g     U@g      Y@g      \@g     @_@g     0a@g     b@g     Pd@g     e@g     pg@g      i@c              #   r   K   | ]/  }t        j                  t        j                  |d z               1 yw)g      4@N)mathdegreesatan).0ds     >/usr/lib/python3/dist-packages/fontTools/varLib/avarPlanner.py	<genexpr>r,   M   s&     HAdll499QX./Hs   57i   )            	   
                     $   0   <   H   `   x            i   r1   c                     | |z
  ||z
  z  S )zOLinearly normalize value in [rangeMin, rangeMax] to [0, 1], with extrapolation. )valuerangeMinrangeMaxs      r+   r   r   l   s    HH!455    c                     || ||z
  z  z   S )zALinear interpolation between a and b, with t typically in [0, 1].rD   )tabs      r+   r   r   q   s    qAE{?rH   c                     t        j                  |      }t        j                  |      }t        j                  |       |z
  ||z
  z  S )zVLogarithmically normalize value in [rangeMin, rangeMax] to [0, 1], with extrapolation.)r&   log)rE   rF   rG   logMinlogMaxs        r+   r   r   v   s:    XXhFXXhFHHUOf$&99rH   c                     t        j                  |      }t        j                  |      }t        j                  || ||z
  z  z         S )zFLogarithmic interpolation between a and b, with t typically in [0, 1].)r&   rN   exp)rJ   rK   rL   logAlogBs        r+   r   r   }   s9    88A;D88A;D88D1t,,--rH   c                    t        j                  t        j                  |            }t        j                  t        j                  |            }t        j                  t        j                  |             |z
  ||z
  z  S )zPAngularly normalize value in [rangeMin, rangeMax] to [0, 1], with extrapolation.)r&   tanradians)rE   rF   rG   tanMintanMaxs        r+   r   r      sV    XXdll8,-FXXdll8,-FHHT\\%()F2vGGrH   c                 L   t        |t              r|}n|D ci c]  }|d }}dx}}|D ]o  }||j                  |d      }|dk(  rd}| |   }t        |       }	|j	                  |	       |j
                  |z  }
||
t        |	j                        z  z  }||
z  }q ||z  S c c}w )z:Measure the perceptual average weight of the given glyphs.   r   glyphset)
isinstancedictgetr   drawwidthabsrE   )r]   glyphsfrequenciesgwght_sumwdth_sum
glyph_name	frequencyglyphpenmults              r+   r   r      s    &$%+,q!t,,Hx 
"#
A6IA~I$x(

3{{Y&D3syy>))D" h) -s   
B!c                    t        |t              r|}n|D ci c]  }|d }}d}d}|D ]U  }||j                  |d      }|dk(  rd}| |   }t               }	|j	                  |	       ||j
                  |z  z  }||z  }W ||z  S c c}w )z.Measure the average width of the given glyphs.r[   r   )r^   r_   r`   r   ra   rb   )
r]   rd   re   rf   rh   freq_sumri   rj   rk   rl   s
             r+   r   r      s    &$%+,q!t,,HH 
"#
A6IA~I$i

3EKK)++I  h) -s   
Bc                    t        |t              r|}n|D ci c]  }|d }}d}d}|D ]f  }||j                  |d      }|dk(  rd}| |   }t        |       }	|j	                  |	       |j
                  |z  }
||
|	j                  z  z  }||
z  }h t        j                  t        j                  ||z               S c c}w )z?Measure the perceptual average slant angle of the given glyphs.r[   r   r\   )
r^   r_   r`   r   ra   rb   slantr&   r'   r(   )r]   rd   re   rf   slnt_sumro   ri   rj   rk   rl   rm   s              r+   r   r      s    &$%+,q!t,,HH 
"#
A6IA~I$X.

3{{Y&D399$$D" LL8h#67888+ -s   
B?c                    ||d      ||d      ||d      }}}| d   ||z  z  }| d   ||z  z  }t        j                  dg|   t         j                  d|| d   |       t        || d   z
        | d   z  dkD  st        || d   z
        | d   z  dkD  rGt         j                  d       t        j                  dg|   t         j                  d	|| d   |       y
y)zSanitize the width axis limits.r   r[      z$Original width axis limits: %g:%g:%gz&Calculated width axis limits: %g:%g:%g皙?z6Calculated width axis min/max do not match user input.z%  Current width axis limits: %g:%g:%gz'  Suggested width axis limits: %g:%g:%gFTrN   inforc   warning)	
userTripledesignTriplepinsmeasurementsminVal
defaultValmaxValcalculatedMinValcalculatedMaxVals	            r+   r   r      s    	\!_%\!_%\!_% JF "!}(;<!!}(;<HH3AjAHH01	 	z!},-
1=D*Q-/0:a=@4GLM3	
	
 	5qM		
 rH   c                    t        t        |             dk  ry||d      ||d      ||d      }}}t        j                  |      }t        j                  |      }t        j                  |      }	| d   | d   z
  | d   | d   z
  z  }
t        j                  ||
|	|z
  z  z         }||z
  ||z
  z  }
| d   |
| d   | d   z
  z  z   }t        j
                  dg|   t        j                  d| d   || d          t        || d   z
        | d   z  dkD  r.t        j                  d	       t        j                  d
g|   t        j                  d| d   || d          | d   | d   z
  | d   | d   z
  z  }
t        j                  ||
||z
  z  z         }||z
  ||z
  z  }
| d   |
| d   | d   z
  z  z   }t        j                  d| d   | d   |       | d   | d   z
  | d   | d   z
  z  }
t        j                  |	|
||	z
  z  z         }||z
  ||z
  z  }
| d   |
| d   | d   z
  z  z   }t        j                  d|| d   | d          yy)z Sanitize the weight axis limits.   Tr   r[   rt   z%Original weight axis limits: %g:%g:%gz'Calculated weight axis limits: %g:%g:%gru   z9Calculated weight axis default does not match user input.z&  Current weight axis limits: %g:%g:%gz:  Suggested weight axis limits, changing default: %g:%g:%gz:  Suggested weight axis limits, changing maximum: %g:%g:%gz:  Suggested weight axis limits, changing minimum: %g:%g:%gF)lensetr&   rN   rR   rw   rc   rx   )ry   rz   r{   r|   r}   r~   r   rO   
logDefaultrP   rJ   ycalculatedDefaultValr   r   s                  r+   r   r   	  s    3z?a 	\!_%\!_%\!_% JF XXfF*%JXXfF	AA	&:a=:a=+HIA!v//0A	
V(A%a=1
1
10M+NNHH4BzBHH111	 *Q-/0:a=@4GOP4	
	

 	HqM qM		
 ]Z]*z!}z!}/LMHHVa:#6778ZJ/0%a=1
1
10M+NNHqMqM		
 ]Z]*z!}z!}/LMHHVa:#6778ZJ/0%a=1
1
10M+NNHqMqM		
 rH   c                    t        j                  dg|   t         j                  d||d      ||d      ||d             t        ||d      | d   z
        dkD  s4t        ||d      | d   z
        dkD  st        ||d      | d   z
        dkD  rVt         j                  d       t        j                  dg|   t         j                  d||d      ||d      ||d             y	y
)zSanitize the slant axis limits.z$Original slant axis limits: %g:%g:%gz&Calculated slant axis limits: %g:%g:%gr   r[   rt   z>Calculated slant axis min/default/max do not match user input.z%  Current slant axis limits: %g:%g:%gz'  Suggested slant axis limits: %g:%g:%gFTrv   )ry   rz   r{   r|   s       r+   r   r   P  s	    HH3AjAHH0\!_%\!_%\!_%	 	La)JqM9:Q>|LO,z!}<=A|LO,z!}<=ATU3	
	
 	5a)a)a)		
 rH   c           	      ^   t        |t              r#|j                  |j                  |j                  f}|\  }}}|t
        }| |i       j                         }|
i }
n|
j                         }
t        j                  d|||       |||f}|	t        j                  dg|	  n|}	|
r-t        j                  dt        |
j                                      |
j                  ||	d   ||	d   ||	d   i       i }i }i }t        |||ht        |
j                               z        D ]  } |||i      }|
|   } | ||      ||<     |!t        j                  d	|        |||	|
|       t        j                  d
t        |             t!        t#        t        |
j                                     dd t#        t        |
j                                     dd       D ]  \  \  }}\  }}|D ch c]  }||cxk  r|k  sn n| }}|s.t%        ||      }t%        ||      }t%        ||	      }t%        ||	      }t        j                  dt        |             t        j                  d|||       |j                         } t'        d|dz         D ]L  }!|||z
  |!z  |dz   z  z   }t        j                  d|        |||i      }t)        ||
      } | ||      | |<   N t        j                  dt        |              i }"t        |       D ]
  }||"| |   <    |||<   |||<   t        |      D ]r  } ||||      }# ||#| |   | |         }$t)        |$|"      }%t        j                  d||%fz         |%||<   |||z
  ||z
  z  ||z
  z  z   }&||%|z
  ||z
  z  ||z
  z  z   ||&<   t |||<   |||<    t        j                  d|t        |             t        j                  d|t        |             t+        d |j                         D              rt        j                  d|       i }i }||fS c c}w )a@  Plan an axis.

    measureFunc: callable that takes a glyphset and an optional
    list of glyphnames, and returns the glyphset-wide measurement
    to be used for the axis.

    normalizeFunc: callable that takes a measurement and a minimum
    and maximum, and normalizes the measurement into the range 0..1,
    possibly extrapolating too.

    interpolateFunc: callable that takes a normalized t value, and a
    minimum and maximum, and returns the interpolated value,
    possibly extrapolating too.

    glyphSetFunc: callable that takes a variations "location" dictionary,
    and returns a glyphset.

    axisTag: the axis tag string.

    axisLimits: a triple of minimum, default, and maximum values for
    the axis. Or an `fvar` Axis object.

    values: a list of output values to map for this axis.

    samples: the number of samples to use when sampling. Default 8.

    glyphs: a list of glyph names to use when sampling. Defaults to None,
    which will process all glyphs.

    designLimits: an optional triple of minimum, default, and maximum values
    represenging the "design" limits for the axis. If not provided, the
    axisLimits will be used.

    pins: an optional dictionary of before/after mapping entries to pin in
    the output.

    sanitizeFunc: an optional callable to call to sanitize the axis limits.
    Nz(Axis limits min %g / default %g / max %gz/Axis design-limits min %g / default %g / max %gzPins %sr   r[   rt   )locationz/Sanitizing axis limit values for the `%s` axis.zCalculated average value:
%szPlanning target values %s.z"Sampling %u points in range %g,%g.zSampling value %g.zSampled average value:
%szPlanned mapping value %g to %g.z%Planned mapping for the `%s` axis:
%sz0Planned normalized mapping for the `%s` axis:
%sc              3   D   K   | ]  \  }}t        ||z
        d k    yw)g{Gz?N)rc   )r)   kvs      r+   r,   zplanAxis.<locals>.<genexpr>  s!     
?A3q1u:
?s    z6Detected identity mapping for the `%s` axis. Dropping.)r^   fvarAxisminValuedefaultValuemaxValueSAMPLESkeyscopyrN   rw   sorteditemsupdater   debugr   ziplistr	   ranger   all)'measureFuncnormalizeFuncinterpolateFuncglyphSetFuncaxisTag
axisLimitsvaluessamplesrd   designLimitsr{   sanitizeFuncr   r   r   tripleoutoutNormalizedaxisMeasurementsrE   r]   designValuerF   	targetMinrG   	targetMaxwtargetValuesnormalizedMinnormalizedMaxnormalizedTargetMinnormalizedTargetMaxvalueMeasurementssamplemeasurementValuerJ   targetMeasurementtargetValuevalueNormalizeds'                                          r+   r   r   q  s   j *h' )):+B+BJDWDWX
'1$HlH~b!&&(|yy{HH2HlH h/FBR\RF4::<01KKl1o,q/l1o	
 CM<:S=MMN F'5)9:5k(3Hf(E%F
 BGLV\41ABII-w7G/HI8;VDJJL!"3B'VDJJL!"12&9 -;494) $*EaX-DH-DEE&x8&x8,YE,YE-vl/CD5w(S,113Aw{+ 	KF8 3v=1MMEII*E2#gu-=>H,UD9K-86-Jk*	K 			.8I0JK-. 	?E9>.u56	? "H':m$L) 	VEeXx8A /$Y/1B91M! -->@PQKII75+:NNO$CJ+ux/?8#/./0 0O .Ai'Y&D(+>AT+TDV .VM/*	V "H':m$[-;^ HH5wMHH; 
?)<)<)>
??I7So Fs   *P*;P*c                 r    |t         }t        t        t        t        | d|||||||rt
              S d      S )a  Plan a weight (`wght`) axis.

    weights: A list of weight values to plan for. If None, the default
    values are used.

    This function simply calls planAxis with values=weights, and the appropriate
    arguments. See documenation for planAxis for more information.
    Nwghtr   r   rd   r   r{   r   )WEIGHTSr   r   r   r   r   )r   r   weightsr   rd   r   r{   sanitizes           r+   r   r     sP    & !'/^  6: rH   c                 r    |t         }t        t        t        t        | d|||||||rt
              S d      S )a  Plan a width (`wdth`) axis.

    widths: A list of width values (percentages) to plan for. If None, the default
    values are used.

    This function simply calls planAxis with values=widths, and the appropriate
    arguments. See documenation for planAxis for more information.
    Nwdthr   )WIDTHSr   r   r   r   r   )r   r   widthsr   rd   r   r{   r   s           r+   r   r   :  sP    & ~!&.]  59 rH   c                 r    |t         }t        t        t        t        | d|||||||rt
              S d      S )a  Plan a slant (`slnt`) axis.

    slants: A list slant angles to plan for. If None, the default
    values are used.

    This function simply calls planAxis with values=slants, and the appropriate
    arguments. See documenation for planAxis for more information.
    Nslntr   )SLANTSr   r   r   r   r   )r   r   slantsr   rd   r   r{   r   s           r+   r   r   `  sP    & ~!&.]  59 rH   c                 V    |t         }t        t        t        t        | d||||||      S )a  Plan a optical-size (`opsz`) axis.

    sizes: A list of optical size values to plan for. If None, the default
    values are used.

    This function simply calls planAxis with values=sizes, and the appropriate
    arguments. See documenation for planAxis for more information.
    opsz)r   r   rd   r   r{   )SIZESr   r   r   r   )r   r   sizesr   rd   r   r{   r   s           r+   r   r     s<    & }! rH   c                     d| |f|z   z  }|r|dz  }n|dz  }|j                         D ]  \  }}|d||fz  z  } |r|dz  }|S )z-Make a designspace snippet for a single axis.zC    <axis tag="%s" name="%s" minimum="%g" default="%g" maximum="%g"z>
z/>z$      <map input="%g" output="%g"/>
z    </axis>)r   )r   axisName	axisLimitmappingdesignspaceSnippetkeyrE   s          r+   r   r     s     	NX*	,  e#d"mmo U
UEeTTU m+rH   c                     t        d      x| d<   }t        j                  D ]  }i |j                  |j                  <    y)z&Add an empty `avar` table to the font.avarN)r   fvaraxessegmentsr   )fontr   axiss      r+   r   r     s:    "6**DL4		 )&(dll#)rH   c           
         d}| d   j                   D ]  }|j                  |k(  s|} n |y|j                  |j                  |j                  f}t
        j                  d|       d| v r%| d   j                  |   }i | d   j                  |<   nd}|6t        |t              r&|j                         D cg c]  }t        |       }}|lt        |t              r\t        j                  j                  d      D cg c]  }t        |       }}t        |      dk(  r|d   |d	   cxk  r	|d
   k  sJ  J d}|Ut        |t              rEi }|j                         D ]-  }|j                  d      \  }}t        |      |t        |      <   / |}~ || j                  |||||||	      \  }}|
rKddlm} |j%                  t'        |      t'        |      D cg c]  }||   	 c}       |j)                          | t
        j                  d|t+        |             |r"d| vrt-        |        || d   j                  |<   nd| v ri | d   j                  |<   t/        ||||      }|S c c}w c c}w c c}w )zProcess a single axis.Nr    zPlanning %s axis.r   :r   r   r[   rt   )r   rd   r   r{   r   )pyplotzExisting %s mapping:
%s)r   r   r   r   r   rN   rw   r   r^   strsplitfloatoptionsr   r   getGlyphSet
matplotlibr   plotr   showr   r   r   )r   planFuncr   r   r   r   rd   r   r{   r   r   r   r   existingMappingr   r*   newPinspinbeforeafterr   mappingNormalizedr   r   r   s                            r+   r   r     s    JV!! <<7"J %%z'>'>
@S@STJHH (+~v,//8)+Vg&j5$*LLN3q%(33J|S$A*1*>*>*D*DS*IJQaJJ"Q<?El1oE	
FE	
F JtS1::< 	2CIIcNMFE%*5\GE&M"	2 !)!	"G %$%+12C+DEaq!E	
 	"+Xw7OP):Vg&T>-/DL!!'*/	 q 4 K@ Fs   5I&<I+I0
c                 >
   | ddl }|j                  dd } ddlm} ddlm} ddl}|j                  dd      }|j                  d	d
d       |j                  ddt        d       |j                  dt        d       |j                  dt        d       |j                  dt        d       |j                  dt        d       |j                  dt        d       |j                  dddd       |j                  d d!t        d"       |j                  d#t        d$       |j                  d%t        d&       |j                  d't        d(       |j                  d)t        d*       |j                  d+t        d,       |j                  d-t        d.       |j                  d/t        d0       |j                  d1t        d2       |j                  d3d4dd5       |j                  d67      }|j                  d8d9dd:       |j                  d;d<dd=       |j                  |       } ||j                  rd>n|j                  rd?nd@A        ||j                        }dB|vrt         j#                  dC       y|j$                  v|j$                  j'                         }	dD|j$                  v rPi }	|j$                  j'                         D ].  }
dD|
v r#|
j'                  dD      \  }}t)        |      |	|<   *dE|	|
<   0 nd}	g }|j+                  t-        |t.        dFdG|j0                  |j2                  |	|j4                  |j6                  |j8                  |j:                  H             |j+                  t-        |t<        dIdJ|j>                  |j2                  |	|j@                  |jB                  |j8                  |j:                  H             |j+                  t-        |tD        dKdL|jF                  |j2                  |	|jH                  |jJ                  |j8                  |j:                  H             |j+                  t-        |tL        dMdN|jN                  |j2                  |	|jP                  |jR                  |j8                  |j:                  H             t         jU                  dO       |D ]  }|stW        |        |jX                  t[        |j                  dPdQR      }n|jX                  }|r(t         jU                  dS|       |j]                  |       yy)Tz3Plan the standard axis mappings for a variable fontNr   r[   )configLogger)TTFontzfonttools varLib.avarPlannerz#Plan `avar` table for variable font)descriptionr   zvarfont.ttfzVariable-font file.)metavarhelpz-oz--output-filezOutput font file name.)typer   z	--weightsz+Space-separate list of weights to generate.z--widthsz*Space-separate list of widths to generate.z--slantsz*Space-separate list of slants to generate.z--sizesz1Space-separate list of optical-sizes to generate.z	--sampleszNumber of samples.z-sz
--sanitize
store_truezSanitize axis limits)actionr   z-gz--glyphsz2Space-separate list of glyphs to use for sampling.z--weight-design-limitsz4min:default:max in design units for the `wght` axis.z--width-design-limitsz4min:default:max in design units for the `wdth` axis.z--slant-design-limitsz4min:default:max in design units for the `slnt` axis.z--optical-size-design-limitsz4min:default:max in design units for the `opsz` axis.z--weight-pinsz=Space-separate list of before:after pins for the `wght` axis.z--width-pinsz=Space-separate list of before:after pins for the `wdth` axis.z--slant-pinsz=Space-separate list of before:after pins for the `slnt` axis.z--optical-size-pinsz=Space-separate list of before:after pins for the `opsz` axis.z-pz--plotzPlot the resulting mapping.F)requiredz-vz	--verbosezRun more verbosely.z-qz--quietzTurn verbosity off.DEBUGWARNINGINFO)levelr   zNot a variable font.r   g      ?r   Weight)r   r   rd   r   r{   r   r   r   Widthr   Slantr   OpticalSizezDesignspace snippet:Tz.avar)	overWritesuffixz	Saving %s)/sysargv	fontToolsr   fontTools.ttLibr   argparseArgumentParseradd_argumentr   intadd_mutually_exclusive_group
parse_argsverbosequietr   rN   errorrd   r   r   appendr   r   r   r   weight_design_limitsweight_pinsr   r   r   r   width_design_limits
width_pinsr   r   slant_design_limits
slant_pinsr   r   optical_size_design_limitsoptical_size_pinsrw   printoutput_filer
   save)argsr  r   r   r  parserlogging_groupr   r   rd   rf   rk   rj   designspaceSnippetssnippetoutfiles                   r+   r   r   #  sI    |xx|&&$$&9 % F <QR
%	   #$Q   #O   #O   "U   #4HI
l<6L   A	    C  
 C  
 C  
 &C  
 L  
 L  
 L  
 L  
 h|2O   777GMk,5J   i3H   %G!//wGMMyv ',,DT>		()~~!%%''.. F^^))+ $!8'(wws|$E9$))$4F5M #F1I$ ??OO 55$$%%	
 >>OO 44##%%	
 >>OO 44##%%	
 ==OO ;;**%%	
  HH#$& 'N "$W\\T'R%%g&		' rH   __main__)N)NNNNN)NNNNNF)NNNNFF)5r  r   fontTools.ttLib.tables._f_v_a_rr   r   fontTools.pens.areaPenr   fontTools.pens.basePenr   fontTools.pens.statisticsPenr   fontTools.varLib.modelsr   r	   fontTools.misc.cliToolsr
   r&   loggingpprintr   __all__	getLoggerrN   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __name__r  exitrD   rH   r+   <module>r.     s}   $ < * * 6 F 6   . g67,
$ 
HsBH	H	4 6

:.H889:&RDNR 	`L 	#R 	#R 	#R 	"J*) 		YxCL zCHHTV rH   