B
    ¶ôJde  ã               @   s¶   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„ de	ƒZ
eddfd	d
„Zdd„ Zdd„ Zdd„ Zddd„Zedkr²ddlZeejƒdkr¬ddlZe e ¡ j¡ eƒ  dS )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               @   s   e Zd Zdd„ Zdd„ ZdS )Úmissingdictc             C   s
   || _ d S )N)Úmissing_func)Úselfr   © r	   úH/var/www/html/venv/lib/python3.7/site-packages/fontTools/cffLib/width.pyÚ__init__   s    zmissingdict.__init__c             C   s
   |   |¡S )N)r   )r   Úvr	   r	   r
   Ú__missing__   s    zmissingdict.__missing__N)Ú__name__Ú
__module__Ú__qualname__r   r   r	   r	   r	   r
   r      s   r   Fc       
         s¦   t |  ¡ ƒ}|d |d  ‰‰ t||  ¡ ˆƒ‰|rT‡ ‡‡fdd„}tˆ ˆd dƒ}n‡‡‡fdd„}tˆˆ d ƒ}t|ƒ}ˆ}x"|D ]}	||| |	 ƒ}|||	< q„W |S )Nr   éÿÿÿÿc                s   | ˆ krˆS ˆS )Nr	   )Úx)ÚmaxxÚstartÚtotalr	   r
   Ú<lambda>   ó    zcumSum.<locals>.<lambda>é   c                s   | ˆ k rˆS ˆS )Nr	   )r   )Úminxr   r   r	   r
   r   !   r   )ÚsortedÚkeysr   ÚvaluesÚranger   )
ÚfÚopr   Ú
decreasingr   ÚmissingÚdomainÚoutr   r   r	   )r   r   r   r   r
   ÚcumSum   s    
r$   c             C   sœ   t | dƒs4ttƒ}x| D ]}||  d7  < qW |} d}x^|  ¡ D ]R\}}||krTqBt|| ƒ}|dkrr||7 }qB|dkrˆ||d 7 }qB||d 7 }qBW |S )NÚitemsr   r   ék   ik  é   é   )Úhasattrr   Úintr%   Úabs)ÚwidthsÚdefaultÚnominalÚdÚwÚcostÚfreqÚdiffr	   r	   r
   ÚbyteCost-   s     

 
r4   c                sÚ   t tƒ}xˆ D ]}||  d7  < qW dt| ¡ ƒ }tˆ ƒtˆ ƒ }}tt||d ƒƒ}t‡ fdd„|D ƒƒ}tˆ ƒd d }xP|D ]H}	tˆ d|	ƒ|| kr q†x,|D ]$}
tˆ |
|	ƒ}||k r¦|}|
}|	}q¦W q†W ||fS )zSBruteforce version.  Veeeeeeeeeeeeeeeeery slow.  Only works for smallests of fonts.r   r(   c             3   s   | ]}t ˆ d |ƒV  qd S )N)r4   )Ú.0r.   )r,   r	   r
   ú	<genexpr>O   s    z+optimizeWidthsBruteforce.<locals>.<genexpr>N)	r   r*   Úmaxr   ÚminÚlistr   Úlenr4   )r,   r/   r0   ZmaxDefaultAdvantageÚminwÚmaxwr"   ZbestCostWithoutDefaultÚbestCostr.   r-   r1   ZbestDefaultZbestNominalr	   )r,   r
   ÚoptimizeWidthsBruteforceB   s$    


r>   c                s&  t ˆdƒs4ttƒ}xˆD ]}||  d7  < qW |‰tˆ ¡ ƒ}|d |d  }}tt||d ƒƒ}tˆtd‰tˆt	d‰tˆtdd‰tˆt	dd‰t
‡fdd	„ƒ‰t
‡fd
d	„ƒ‰
t
‡
‡‡fdd	„ƒ‰	t
‡fdd	„ƒ‰t
‡fdd	„ƒ‰t
‡‡fdd	„ƒ‰t
‡‡	fdd	„ƒ‰ t|‡ fdd	„d‰ˆ ˆ }ˆ	ˆ ˆ ˆ  }g }	|ˆˆ kr¬ˆˆd ˆd g}
x¦|
D ]@}x.ˆ| r˜ˆ| ˆ|d  kr˜|d8 }qlW |	 |¡ qfW n\ˆˆd ˆd g}
xH|
D ]@}x.ˆ| röˆ| ˆ|d  krö|d7 }qÊW |	 |¡ qÄW t|	‡‡fdd	„d}|ˆfS )zÍGiven 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.r%   r   r   r   )r   T)r   r    c                s$   ˆ |  ˆ | d   ˆ | d  d  S )Nél   il  é   r	   )r   )ÚcumFrqUr	   r
   r   v   r   z optimizeWidths.<locals>.<lambda>c                s$   ˆ |  ˆ | d   ˆ | d  d  S )Nr?   il  r@   r	   )r   )ÚcumFrqDr	   r
   r   w   r   c                s   ˆ|  ˆ |   ˆ|   S )Nr	   )r   )Ú	nomnCostDÚ	nomnCostUr,   r	   r
   r   x   r   c                s(   t ˆ |  ˆ | d  d ˆ | d  d ƒS )Nr?   r'   il  r(   )r7   )r   )ÚcumMaxUr	   r
   r   {   r   c                s(   t ˆ |  ˆ | d  d ˆ | d  d ƒS )Nr?   r'   il  r(   )r7   )r   )ÚcumMaxDr	   r
   r   |   r   c                s   t ˆ|  ˆ |  ƒS )N)r7   )r   )Ú	dfltCostDÚ	dfltCostUr	   r
   r   }   r   c                s   ˆ|  ˆ |   S )Nr	   )r   )ÚdfltCostÚnomnCostr	   r
   r   €   r   c                s   ˆ |  S )Nr	   )r   )r=   r	   r
   r   ƒ   r   )Úkeyr?   il  c                s   t ˆ| ˆ ƒS )N)r4   )r-   )r.   r,   r	   r
   r   •   r   )r)   r   r*   r   r   r9   r   r$   r   r7   r   r8   Úappend)r,   r/   r0   r   r;   r<   r"   ZbestCZdfltCZendsZstartsr   r-   r	   )r=   rB   rA   rF   rE   rI   rG   rH   r.   rJ   rC   rD   r,   r
   ÚoptimizeWidths_   sH    


"
"rM   Nc       	   
   C   sÂ   ddl }|jdtjd}|jddtddd	 |jd
ddddd | | ¡} xr| jD ]h}t|ƒ}|d }dd„ |j	 
¡ D ƒ}| jrŽt|ƒ\}}nt|ƒ\}}tdt|ƒ||t|||ƒf ƒ qRW dS )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ÚactionrU   Úhmtxc             S   s   g | ]}|d  ‘qS )r   r	   )r5   Úmr	   r	   r
   ú
<listcomp>«   s    zmain.<locals>.<listcomp>z+glyphs=%d default=%d nominal=%d byteCost=%d)ÚargparseÚArgumentParserÚmainÚ__doc__Úadd_argumentÚstrÚ
parse_argsrO   r   Zmetricsr   rV   r>   rM   Úprintr:   r4   )	Úargsr]   ÚparserZfontfileZfontrZ   r,   r-   r.   r	   r	   r
   r_   ™   s"    

r_   Ú__main__r   )N)r`   ZfontTools.ttLibr   Úcollectionsr   Úoperatorr   Ú	functoolsr   Údictr   r$   r4   r>   rM   r_   r   Úsysr:   ÚargvÚdoctestÚexitÚtestmodÚfailedr	   r	   r	   r
   Ú<module>   s    :
