U
    #vh                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddg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rddlZeejdkrd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)reduceoptimizeWidthsmainc                   @   s   e Zd Zdd Zdd ZdS )missingdictc                 C   s
   || _ d S Nmissing_func)selfr    r   :/tmp/pip-unpacked-wheel-1ufboor8/fontTools/cffLib/width.py__init__   s    zmissingdict.__init__c                 C   s
   |  |S r	   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|}}|D ]}	||| |	 }|||	< q|S )Nr   c                    s   |  krS S r	   r   x)maxxstarttotalr   r   <lambda>"       zcumSum.<locals>.<lambda>   c                    s   |  k rS S r	   r   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s0tt}| D ]}||  d7  < q|} d}|  D ]R\}}||krNq<t|| }|dkrl||7 }q<|dkr||d 7 }q<||d 7 }q<|S )Nitemsr   r   k   ik        )hasattrr   intr*   abs)widthsdefaultnominaldwcostfreqZdiffr   r   r   byteCost2   s     

r8   c                    s   t t} D ]}||  d7  < qdt|  }t t  }}tt||d }t fdd|D }t d d }|D ]D}	t d|	|| krq|D ]$}
t |
|	}||k r|}|
}|	}qq||fS )zSBruteforce version.  Veeeeeeeeeeeeeeeeery slow.  Only works for smallests of fonts.r   r-   c                 3   s   | ]}t  d |V  qd S r	   r8   ).0r3   r1   r   r   	<genexpr>T   s     z+optimizeWidthsBruteforce.<locals>.<genexpr>N)	r   r/   maxr!   minlistr"   lenr8   )r1   r4   r5   ZmaxDefaultAdvantageminwmaxwr'   ZbestCostWithoutDefaultbestCostr3   r2   r6   ZbestDefaultZbestNominalr   r;   r   optimizeWidthsBruteforceG   s$    rD   c                    s  t ds0tt}D ]}||  d7  < q|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}
|
D ]<}| r| |d  kr|d8 }qd|	| q`nTd d g}
|
D ]<}| r| |d  kr|d7 }q|	| qt|	fdd	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.r*   r   r   r   )r$   T)r$   r%   c                    s$    |   | d    | d  d  S Nl   l     r   r   )cumFrqUr   r   r   |   r   z optimizeWidths.<locals>.<lambda>c                    s$    |   | d    | d  d  S rE   r   r   )cumFrqDr   r   r      r   c                    s   |   |   |   S r	   r   r   )	nomnCostD	nomnCostUr1   r   r   r      r   c                    s(   t  |   | d  d  | d  d S NrF   r,   rG   r-   r=   r   )cumMaxUr   r   r      r   c                    s(   t  |   | d  d  | d  d S rM   rN   r   )cumMaxDr   r   r      r   c                    s   t |   |  S r	   rN   r   )	dfltCostD	dfltCostUr   r   r      r   c                    s   |   |   S r	   r   r   )dfltCostnomnCostr   r   r      r   c                    s    |  S r	   r   r   )rC   r   r   r      r   )keyrF   rG   c                    s   t |  S r	   r9   )r2   )r3   r1   r   r   r      r   )r.   r   r/   r   r    r?   r"   r)   r   r=   r   r>   append)r1   r4   r5   r    rA   rB   r'   ZbestCZdfltCZendsZstartsr   r2   r   )rC   rJ   rI   rP   rO   rS   rQ   rR   r3   rT   rK   rL   r1   r   r   d   sX    




  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 || } | jD ]h}t|}|d }dd |j	
 D }| jrt|\}}nt|\}}tdt|||t|||f  qPd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actionr^   hmtxc                 S   s   g | ]}|d  qS )r   r   )r:   mr   r   r   
<listcomp>   s     zmain.<locals>.<listcomp>z+glyphs=%d default=%d nominal=%d byteCost=%d)argparseArgumentParserr   __doc__add_argumentstr
parse_argsrX   r   Zmetricsr!   r_   rD   r   printr@   r8   )	argsrf   parserZfontfilefontrc   r1   r2   r3   r   r   r   r      s@        

__main__r   )N)rh   ZfontTools.ttLibr   collectionsr   operatorr   	functoolsr   __all__dictr   r)   r8   rD   r   r   r   sysr@   argvdoctestexittestmodfailedr   r   r   r   <module>   s"   C
$