
    jke                         d Z ddlmZ ddlmZ ddlmZ ddlmZ  G d de	      Z
eddfd	Zd
 Zd Zd ZddZedk(  rPddlZ eej&                        dk(  r/ddlZ ej*                   ej,                         j.                          e        yy)aF  T2CharString glyph width optimizer.

CFF glyphs whose width equals the CFF Private dictionary's ``defaultWidthX``
value do not need to specify their width in their charstring, saving bytes.
This module determines the optimum ``defaultWidthX`` and ``nominalWidthX``
values for a font, when provided with a list of glyph widths.    )TTFont)defaultdict)add)reducec                       e Zd Zd Zd Zy)missingdictc                     || _         y Nmissing_func)selfr   s     8/usr/lib/python3/dist-packages/fontTools/cffLib/width.py__init__zmissingdict.__init__   s
    (    c                 $    | j                  |      S r
   r   )r   vs     r   __missing__zmissingdict.__missing__   s      ##r   N)__name__
__module____qualname__r   r    r   r   r   r      s    )$r   r   Fc                 6  
 t        | j                               }|d   |d   c
t        || j                               |r
fd}t	        
dz
  d      }nfd}t	        
dz         }t        |      }}|D ]  }	 ||| |	         }|||	<    |S )Nr   c                     | kD  rS S r
   r   )xmaxxstarttotals    r   <lambda>zcumSum.<locals>.<lambda>       QXE 5 r      c                     | k  rS S r
   r   )r   minxr   r   s    r   r   zcumSum.<locals>.<lambda>"   r    r   )sortedkeysr   valuesranger   )fopr   
decreasingr%   missingdomainoutr   r   r   r#   r   s     `       @@@r   cumSumr.      s    !&&(Da$r(JD$2qxxz5)E8tTAXr*8tTAX&
g
CA q!A$KA Jr   c                    t        | d      s%t        t              }| D ]  }||xx   dz  cc<    |} d}| j                         D ]:  \  }}||k(  rt	        ||z
        }|dk  r||z  }%|dk  r	||dz  z  }3||dz  z  }< |S )Nitemsr!   r   k   ik        )hasattrr   intr0   abs)widthsdefaultnominaldwcostfreqdiffs           r   byteCostr?   /   s    67# 	AaDAID	D<<> 	4<1w;3;DLDT\D1HDD1HD	 Kr   c                     t        t              } D ]  }||xx   dz  cc<    dt        |j                               z  }t	               t               }}t        t        ||dz               }t	         fd|D              }t               dz  dz   }|D ]6  }	t         d|	      ||z   kD  r|D ]  }
t         |
|	      }||k  s|}|
}|	} 8 fS )zSBruteforce version.  Veeeeeeeeeeeeeeeeery slow.  Only works for smallests of fonts.r!   r3   c              3   8   K   | ]  }t        d |        y wr
   r?   ).0r9   r7   s     r   	<genexpr>z+optimizeWidthsBruteforce.<locals>.<genexpr>Q   s      WW&$!@ Ws   N)	r   r5   maxr&   minlistr'   lenr?   )r7   r:   r;   maxDefaultAdvantageminwmaxwr,   bestCostWithoutDefaultbestCostr9   r8   r<   bestDefaultbestNominals   `             r   optimizeWidthsBruteforcerP   D   s     	CA 	!	 c!((*o-Vc&k$D%dQh'(F  WPV WW6{Q"H &FD'*X8K-KK 	&GFGW5Dh%%	&& ##r   c                     t         d      s%t        t              } D ]  }||xx   dz  cc<    | t         j	                               }|d   |d   }}t        t        ||dz               }t         t              t         t              t         t        d      t         t        d      t        fd      t        fd	      t         fd
      t        fd      t        fd      t        fd      t        fd      t        |fd         }      z
  }g }	|   k(  rPdz
  dz
  g}
|
D ]?  }|   r'|   |dz
     k(  r|dz  }|   r|   |dz
     k(  r|	j                  |       A nOdz   dz   g}
|
D ]?  }|   r'|   |dz      k(  r|dz  }|   r|   |dz      k(  r|	j                  |       A t        |	 fd      }|fS )zGiven a list of glyph widths, or dictionary mapping glyph width to number of
    glyphs having that, returns a tuple of best CFF default and nominal glyph widths.

    This algorithm is linear in UPEM+numGlyphs.r0   r!   r   r   )r)   T)r)   r*   c                 8    |    | dz
     z   | dz
     dz  z   S Nl   l     r   )r   cumFrqUs    r   r   z optimizeWidths.<locals>.<lambda>y   ,    '!*wq3w//'!d(2Ca2GG r   c                 8    |    | dz      z   | dz      dz  z   S rS   r   )r   cumFrqDs    r   r   z optimizeWidths.<locals>.<lambda>|   rX   r   c                 &    |    |    z   |    z
  S r
   r   )r   	nomnCostD	nomnCostUr7   s    r   r   z optimizeWidths.<locals>.<lambda>~   s    Yq\IaL%@6!9%L r   c                 H    t        |    | dz
     dz  | dz
     dz        S NrT   r2   rU   r3   rE   )r   cumMaxUs    r   r   z optimizeWidths.<locals>.<lambda>   0    #gaj'!c'"2Q"6D8IA8MN r   c                 H    t        |    | dz      dz  | dz      dz        S r_   r`   )r   cumMaxDs    r   r   z optimizeWidths.<locals>.<lambda>   rb   r   c                 (    t        |    |          S r
   r`   )r   	dfltCostD	dfltCostUs    r   r   z optimizeWidths.<locals>.<lambda>   s    S1y|%D r   c                     |    |    z
  S r
   r   )r   dfltCostnomnCosts    r   r   z optimizeWidths.<locals>.<lambda>   s    Xa[8A;%> r   c                     |    S r
   r   )r   rM   s    r   r   z optimizeWidths.<locals>.<lambda>   s     r   )keyrT   rU   c                     t        |       S r
   rB   )r8   r9   r7   s    r   r   z optimizeWidths.<locals>.<lambda>   s    HVWg,N r   )r4   r   r5   r$   r%   rG   r'   r.   r   rE   r   rF   append)r7   r:   r;   r%   rJ   rK   r,   bestCdfltCendsstartsr   r8   rM   rZ   rW   rd   ra   ri   rf   rg   r9   rj   r\   r]   s   `            @@@@@@@@@@@@r   optimizeWidthsrs   a   sG    67# 	AaDAID	&++- Da$r($D%dQh'(F V$GV$GV5GV5G GI GI LMH NI NI DEH >?H &34G WEW 11ED	'""7S='D.9 	E%.WU^wuqy7I%I
 %.WU^wuqy7I%IKK	
 7S='D.9 	E%.WU^wuqy7I%I
 %.WU^wuqy7I%IKK	 $NOGGr   Nc                    ddl }|j                  dt        j                        }|j	                  ddt
        dd	       |j	                  d
dddd       |j                  |       } | j                  D ]  }t        |      }|d   }|j                  j                         D cg c]  }|d   	 }}| j                  rt        |      \  }}	nt        |      \  }}	t        dt        |      ||	t!        |||	      fz          yc c}w )z4Calculate optimum defaultWidthX/nominalWidthX valuesr   Nzfonttools cffLib.width)descriptioninputsFILE+zInput TTF files)metavartypenargshelpz-bz--brute-forcebrute
store_truez$Use brute-force approach (VERY slow))destactionr|   hmtxz+glyphs=%d default=%d nominal=%d byteCost=%d)argparseArgumentParsermain__doc__add_argumentstr
parse_argsrv   r   metricsr&   r}   rP   rs   printrH   r?   )
argsr   parserfontfilefontr   mr7   r8   r9   s
             r   r   r      s    $$ LL % F &s#<M   3   T"DKK 
hF| $ 3 3 561!A$66::7?GW-f5GW96{GWhvw.PQR	

 7s   "D__main__r!   r
   )r   fontTools.ttLibr   collectionsr   operatorr   	functoolsr   dictr   r.   r?   rP   rs   r   r   sysrH   argvdoctestexittestmodfailedr   r   r   <module>r      s   A # #  $$ $ A% .*$:@F!
H z
388}"))*F r   