a
    ׶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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)reducec                   @   s   e Zd Zdd Zdd ZdS )missingdictc                 C   s
   || _ d S Nmissing_func)selfr	    r   f/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/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   k        )hasattrr   intr(   abs)widthsdefaultnominaldwcostfreqdiffr   r   r   byteCost-   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   ).0r2   r0   r   r   	<genexpr>O   r   z+optimizeWidthsBruteforce.<locals>.<genexpr>N)	r   r.   maxr   minlistr    lenr8   )r0   r3   r4   ZmaxDefaultAdvantageminwmaxwr%   ZbestCostWithoutDefaultbestCostr2   r1   r5   ZbestDefaultZbestNominalr   r;   r   optimizeWidthsBruteforceB   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   v   r   z optimizeWidths.<locals>.<lambda>c                    s$    |   | d    | d  d  S rE   r   r   )cumFrqDr   r   r   w   r   c                    s   |   |   |   S r   r   r   )	nomnCostD	nomnCostUr0   r   r   r   x   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   r*   c                    s   t |  S r   r9   )r1   )r2   r0   r   r   r      r   )r-   r   r.   r   r   r?   r    r'   r   r=   r   r>   append)r0   r3   r4   r   rA   rB   r%   ZbestCZdfltCZendsZstartsr   r1   r   )rC   rJ   rI   rP   rO   rS   rQ   rR   r2   rT   rK   rL   r0   r   optimizeWidths_   sH    
  rW   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>   r   zmain.<locals>.<listcomp>z+glyphs=%d default=%d nominal=%d byteCost=%d)argparseArgumentParsermain__doc__add_argumentstr
parse_argsrY   r   Zmetricsr   r`   rD   rW   printr@   r8   )	argsrg   parserZfontfilefontrd   r0   r1   r2   r   r   r   ri      s(    

ri   __main__r   )N)rj   ZfontTools.ttLibr   collectionsr   operatorr   	functoolsr   dictr   r'   r8   rD   rW   ri   r   sysr@   argvdoctestexittestmodfailedr   r   r   r   <module>   s    :
