o
    Ðùae  ã                   @   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rVddlZe e ¡ j¡ eƒ  dS 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   ú8/usr/lib/python3/dist-packages/fontTools/cffLib/width.pyÚ__init__   ó   
zmissingdict.__init__c                 C   s
   |   |¡S r   r   )r
   Úvr   r   r   Ú__missing__   r   zmissingdict.__missing__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r      s    r   Fc           
         s¢   t |  ¡ ƒ}|d |d ‰‰ t||  ¡ ˆƒ‰|r*‡ ‡‡fdd„}tˆ ˆd dƒ}n‡‡‡fdd„}tˆˆ d ƒ}t|ƒ}ˆ}|D ]}	||| |	 ƒ}|||	< qA|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ƒsttƒ}| D ]
}||  d7  < q|} d}|  ¡ D ])\}}||kr'qt|| ƒ}|dkr6||7 }q|dkrA||d 7 }q||d 7 }q|S )NÚitemsr   r   ék   ék  é   é   )Úhasattrr   Úintr)   Úabs)ÚwidthsÚdefaultÚnominalÚdÚwÚcostZfreqZdiffr   r   r   ÚbyteCost-   s   


r7   c                    sÎ   t tƒ}ˆ D ]
}||  d7  < qdt| ¡ ƒ }tˆ ƒtˆ ƒ}}tt||d ƒƒ}t‡ fdd„|D ƒƒ}tˆ ƒd d }|D ]"}	tˆ d|	ƒ|| krMq@|D ]}
tˆ |
|	ƒ}||k ra|}|
}|	}qOq@||fS )zSBruteforce version.  Veeeeeeeeeeeeeeeeery slow.  Only works for smallests of fonts.r   r-   c                 3   s    | ]	}t ˆ d |ƒV  qd S r   ©r7   )Ú.0r3   ©r1   r   r   Ú	<genexpr>O   s   € z+optimizeWidthsBruteforce.<locals>.<genexpr>N)	r   r/   Úmaxr    ÚminÚlistr!   Úlenr7   )r1   r4   r5   ZmaxDefaultAdvantageÚminwÚmaxwr&   ZbestCostWithoutDefaultÚbestCostr3   r2   r6   ZbestDefaultZbestNominalr   r:   r   ÚoptimizeWidthsBruteforceB   s(   €ûrC   c                    s:  t ˆdƒst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 }ˆ| rÑˆ| ˆ|d  ks¿|	 |¡ q¯n6ˆˆd ˆd g}
|
D ]*}ˆ| rˆ| ˆ|d  kr|d7 }ˆ| rˆ| ˆ|d  ksõ|	 |¡ qã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   él  é   r   r   )ÚcumFrqUr   r   r   v   ó   $ z optimizeWidths.<locals>.<lambda>c                    s$   ˆ |  ˆ | d   ˆ | d  d  S rD   r   r   )ÚcumFrqDr   r   r   w   rI   c                    s   ˆ|  ˆ |   ˆ|   S r   r   r   )Ú	nomnCostDÚ	nomnCostUr1   r   r   r   x   s    c                    s(   t ˆ |  ˆ | d  d ˆ | d  d ƒS ©NrE   r,   rF   r-   ©r<   r   )ÚcumMaxUr   r   r   {   ó   ( c                    s(   t ˆ |  ˆ | d  d ˆ | d  d ƒS rM   rN   r   )ÚcumMaxDr   r   r   |   rP   c                    s   t ˆ|  ˆ |  ƒS r   rN   r   )Ú	dfltCostDÚ	dfltCostUr   r   r   }   s    c                    s   ˆ|  ˆ |   S r   r   r   )ÚdfltCostÚnomnCostr   r   r   €   r   c                    s   ˆ |  S r   r   r   )rB   r   r   r   ƒ   s    )ÚkeyrE   r+   c                    s   t ˆ| ˆ ƒS r   r8   )r2   )r3   r1   r   r   r   •   s    )r.   r   r/   r   r   r>   r!   r(   r   r<   r   r=   Úappend)r1   r4   r5   r   r@   rA   r&   ZbestCZdfltCZendsZstartsr   r2   r   )rB   rJ   rH   rQ   rO   rT   rR   rS   r3   rU   rK   rL   r1   r   ÚoptimizeWidths_   sN   
ÿý ÿrX   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 ]4}t|ƒ}|d }dd„ |j	 
¡ D ƒ}| jrFt|ƒ\}}nt|ƒ\}}tdt|ƒ||t|||ƒf ƒ q(dS )z4Calculate optimum defaultWidthX/nominalWidthX valuesr   Nzfonttools cffLib.width)ÚdescriptionÚinputsZ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   )r9   Ú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_argsrZ   r   Zmetricsr    r`   rC   rX   Úprintr?   r7   )	Úargsrg   ÚparserZfontfileZfontrd   r1   r2   r3   r   r   r   ri   ™   s*   þÿÿ

"øri   Ú__main__r   r   )rj   ZfontTools.ttLibr   Úcollectionsr   Úoperatorr   Ú	functoolsr   Údictr   r(   r7   rC   rX   ri   r   Úsysr?   ÚargvZdoctestÚexitZtestmodZfailedr   r   r   r   Ú<module>   s$   
:
û