o
    <­ÔZX3  ã                   @   sú   d Z dZddlZddlZddlZddlZddlmZ ddlm	Z	 ddlm
Z
 zddlmZ W n ey=   ddlmZ Y nw g d¢Zd	Zd
ZdZdZdZdZdZdZdZG dd„ dƒZddlmZmZmZmZ G dd„ dƒZdd„ Zedkr{eƒ  dS dS )z3.4.22a”  This provides some general-purpose tools for finding fonts.

The FontFinder object can search for font files.  It aims to build
a catalogue of fonts which our framework can work with.  It may be useful
if you are building GUIs or design-time interfaces and want to present users
with a choice of fonts.

There are 3 steps to using it
1. create FontFinder and set options and directories
2. search
3. query

>>> import fontfinder
>>> ff = fontfinder.FontFinder()
>>> ff.addDirectories([dir1, dir2, dir3])
>>> ff.search()
>>> ff.getFamilyNames()   #or whichever queries you want...

Because the disk search takes some time to find and parse hundreds of fonts,
it can use a cache to store a file with all fonts found. The cache file name

For each font found, it creates a structure with
- the short font name
- the long font name
- the principal file (.pfb for type 1 fonts), and the metrics file if appropriate
- the time modified (unix time stamp)
- a type code ('ttf')
- the family name
- bold and italic attributes

One common use is to display families in a dialog for end users;
then select regular, bold and italic variants of the font.  To get
the initial list, use getFamilyNames; these will be in alpha order.

>>> ff.getFamilyNames()
['Bitstream Vera Sans', 'Century Schoolbook L', 'Dingbats', 'LettErrorRobot',
'MS Gothic', 'MS Mincho', 'Nimbus Mono L', 'Nimbus Roman No9 L',
'Nimbus Sans L', 'Vera', 'Standard Symbols L',
'URW Bookman L', 'URW Chancery L', 'URW Gothic L', 'URW Palladio L']

One can then obtain a specific font as follows

>>> f = ff.getFont('Bitstream Vera Sans', bold=False, italic=True)
>>> f.fullName
'Bitstream Vera Sans'
>>> f.fileName
'C:\code\reportlab\fonts\Vera.ttf'
>>>

It can also produce an XML report of fonts found by family, for the benefit
of non-Python applications.

Future plans might include using this to auto-register fonts; and making it
update itself smartly on repeated instantiation.
é    N)Úpickle)Ú	quoteattr©ÚasBytes)Úmd5)z.ttfz.ttcz.otfz.pfbz.pfaé   é   é   é   é    é@   i   i   i   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚFontDescriptorzƒThis is a short descriptive record about a font.

    typeCode should be a file extension e.g. ['ttf','ttc','otf','pfb','pfa']
    c                 C   sL   d | _ d | _d | _d | _d| _d| _d| _d| _d | _d | _	d | _
d| _d S )NFr   )ÚnameÚfullNameÚ
familyNameÚ	styleNameÚisBoldÚisItalicÚisFixedPitchÚ
isSymbolicÚtypeCodeÚfileNameÚmetricsFileNameÚtimeModified©Úself© r   úJ/var/www/html/env/lib/python3.10/site-packages/reportlab/lib/fontfinder.pyÚ__init__X   s   
zFontDescriptor.__init__c                 C   s
   d| j  S )NzFontDescriptor(%s))r   r   r   r   r   Ú__repr__h   s   
zFontDescriptor.__repr__c                 C   sP   g }| j  ¡ D ]\}}|dvr|r| d|tt|ƒƒf ¡ qdd |¡ d S )z Return an XML tag representation)r   z%s=%sz<font ú z/>)Ú__dict__ÚitemsÚappendr   ÚstrÚjoin)r   ÚattrsÚkÚvr   r   r   ÚgetTagk   s   €zFontDescriptor.getTagN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r)   r   r   r   r   r   S   s
    r   )Úrl_isdirÚ	rl_isfileÚ
rl_listdirÚrl_getmtimec                   @   s~   e Zd Zg ddddfdd„Zddd„Zddd	„Zd
d„ Zdd„ Zdd„ Zdd„ Z	ddd„Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )Ú
FontFinderTFNc                 C   sf   || _ || _|d u rt ¡ }|pd| _tƒ | _|| _|  |¡ g | _	g | _
g | _i | _i | _i | _d S )NÚutf8)ÚuseCacheÚvalidateÚsysÚgetfilesystemencodingÚ_fsEncodingÚsetÚ_dirsÚ_recurÚaddDirectoriesÚ_fontsÚ_skippedFilesÚ	_badFilesÚ_fontsByNameÚ_fontsByFamilyÚ_fontsByFamilyBoldItalic)r   Údirsr4   r5   ÚrecurÚ
fsEncodingr   r   r   r   v   s   


zFontFinder.__init__c                 C   sn   t |ƒr/| j |¡ |d ur|r3n| jr1t |¡D ]\}}}|D ]}| j tj ||¡¡ q qd S d S d S d S ©N)r.   r:   Úaddr;   ÚosÚwalkÚpathr%   )r   ÚdirNamerD   ÚrÚDÚFÚdr   r   r   ÚaddDirectory‰   s   ÿüzFontFinder.addDirectoryc                 C   s   |D ]	}| j ||d� qd S )N)rD   )rP   )r   ÚdirNamesrD   rK   r   r   r   r<   “   s   ÿzFontFinder.addDirectoriesc                    s|   | j s'| j}|D ]}|j}|du rq|| j v r | j |  |¡ q|g| j |< q| j‰ t‡ fdd„| j  ¡ D ƒƒ}| ¡  |S )z2Returns a list of the distinct font families foundNc                 3   ó   � | ]	}t |ˆ d �V  qdS ©)ÚencNr   ©Ú.0Ú_©rE   r   r   Ú	<genexpr>£   ó   € z,FontFinder.getFamilyNames.<locals>.<genexpr>)rA   r=   r   r#   r8   ÚlistÚkeysÚsort)r   ÚfontsÚfontÚfamÚnamesr   rX   r   ÚgetFamilyNames—   s   

zFontFinder.getFamilyNamesc                 C   s   | j  |g ¡S )z5Return list of all font objects with this family name)rA   Úget)r   r   r   r   r   ÚgetFontsInFamily§   s   zFontFinder.getFontsInFamilyc                 C   sš   g }|  d¡ |  d¡ | jD ]}|  dt|ƒ ¡ q|  ¡ D ]#}|rB|  dt|ƒ ¡ |  |¡D ]}|  d| ¡  ¡ q1|  d¡ q|  d¡ d |¡S )	z.Reports on all families found as XML.
        z7<?xml version="1.0" encoding="UTF-8" standalone="yes"?>z<font_families>z    <directory name=%s/>z    <family name=%s>z        z    </family>z</font_families>Ú
)r#   r:   r   rb   rd   r)   r%   )r   ÚlinesrK   r   r_   r   r   r   ÚgetFamilyXmlReport«   s   



€

zFontFinder.getFamilyXmlReportc                 K   sL   g }| j D ]}d}| ¡ D ]\}}t||dƒ|krd}q|r#| |¡ q|S )z%This is a general lightweight search.TNF)r=   r"   Úgetattrr#   )r   ÚkwdsÚselectedr_   ÚOKr'   r(   r   r   r   ÚgetFontsWithAttributes¼   s   
€
€z!FontFinder.getFontsWithAttributesc                 C   sD   | j D ]}|j|kr|j|kr|j|kr|  S qtd|||f ƒ‚)z$Try to find a font matching the specz+Cannot find font %s with bold=%s, italic=%s)r=   r   r   r   ÚKeyError)r   r   ÚboldÚitalicr_   r   r   r   ÚgetFontÈ   s   



€zFontFinder.getFontc                    sH   | j ‰ td ‡ fdd„t| jƒD ƒ¡ƒ ¡ }ddlm} |d| ƒ}|S )zUBase this on the directories...same set of directories
        should give same cacheó    c                 3   rR   rS   r   rU   rX   r   r   rY   ×   rZ   z/FontFinder._getCacheFileName.<locals>.<genexpr>r   )Úget_rl_tempfilezfonts_%s.dat)r8   r   r%   Úsortedr:   Ú	hexdigestÚreportlab.lib.utilsrr   )r   Úhashrr   Úfnr   rX   r   Ú_getCacheFileNameÓ   s
   &zFontFinder._getCacheFileNamec                 C   s"   t |dƒ}t | |¡ | ¡  d S )NÚwb)Úopenr   ÚdumpÚclose)r   r   Úfr   r   r   ÚsaveÜ   s   
zFontFinder.savec                 C   s.   t |dƒ}t |¡}| ¡  | j |j¡ d S )NÚrb)rz   r   Úloadr|   r!   Úupdate)r   r   r}   Úfinder2r   r   r   r€   á   s   

zFontFinder.loadc              
   C   sÌ  t  ¡ }| jstdƒ‚| jr#|  ¡ }t|ƒr#z|  |¡ W d S    Y ddlm	} | jD �])}zt
|ƒ}W n   Y q,|D �]}tj |¡\}}| ¡ tv �rUtƒ }	tj tj ||¡¡ |	_}zt|ƒ|	_W n   | j |¡ Y q=| ¡ }|d dkrƒ|dd … }||	_|dv r‘| j |¡ n¾|dv r×ddlm}
m} z	|
|| jd	�}W n |yµ   | j |¡ Y q=w |j|	_|j|	_|j |	_ |j!|	_!t"t"|j#@ k|	_$t%t%|j#@ k|	_&nx|d
k�rOttj ||d ¡ƒrötj tj ||d ¡¡|	_'n"ttj ||d ¡ƒ�rtj tj ||d ¡¡|	_'n| j |¡ q=ddl(m)} ||	j'ƒ\}}|d |	_| *d|	j¡|	_| *dd ¡|	_!t+| *dd¡ƒdk|	_&d| *dd¡ ¡ v |	_$| j, |	¡ q=q,| j�r`|  -|¡ t  ¡ }d S )NzbFont search path is empty!  Please specify search directories using addDirectory or addDirectoriesr   )ÚST_MTIMEÚ.r   )ÚotfÚpfa)ÚttfÚttc)Ú
TTFontFileÚTTFError)r5   Úpfbz.afmz.AFM)ÚparseAFMFileÚFontNameÚFullNameÚ
FamilyNameÚItalicAngleg        rn   ÚWeightÚ ).ÚtimeÚclockr:   Ú
ValueErrorr4   rx   r/   r€   Ústatrƒ   r0   rH   rJ   ÚsplitextÚlowerÚ
EXTENSIONSr   Únormpathr%   r   r1   r   r>   r#   r   Úreportlab.pdfbase.ttfontsr‰   rŠ   r5   r?   r   r   r   r   ÚFF_FORCEBOLDÚflagsr   Ú	FF_ITALICr   r   Úreportlab.pdfbase.pdfmetricsrŒ   rc   Úfloatr=   r~   )r   ÚstartedÚcfnrƒ   rK   Ú	fileNamesr   ÚrootÚextr}   r‰   rŠ   r_   rŒ   ÚinfoÚglyphsÚfinishedr   r   r   Úsearchç   s†   

þ

€Æ;
zFontFinder.searchrF   )FF)r*   r+   r,   r   rP   r<   rb   rd   rg   rl   rp   rx   r~   r€   r©   r   r   r   r   r2   u   s    



	r2   c                  C   s  ddl m}  tƒ }d|_d|_dd l }| d¡ tj tj 	|j
¡d¡}| |¡ | ¡  tdƒ t| ¡ ƒ tdƒ | ¡ D ]}td| ƒ q?tƒ  tjj}|d	ƒ | d
¡D ]	}|d|j ƒ qXtƒ  |dƒ |jddd�D ]	}||jd ƒ qptƒ  tdƒ t| ¡ ƒ d S )Nr   )Ú	rl_configTzC:\windows\fontsr^   zcache file name...zfamilies...z	%szfonts called Vera:zBitstream Vera Sansz %szBold fonts
	F)r   r   r    zfamily report)Ú	reportlabrª   r2   r4   r5   rP   rH   rJ   r%   ÚdirnameÚ__file__r©   Úprintrx   rb   r6   ÚstdoutÚwriterd   r   rl   r   rg   )rª   Úffr«   Ú	rlFontDirr   Úoutwr_   r   r   r   Útest@  s4   

r´   Ú__main__) Ú__version__r-   r6   r“   rH   Útempfileru   r   Úxml.sax.saxutilsr   r   Úhashlibr   ÚImportErrorr™   ÚFF_FIXEDÚFF_SERIFÚFF_SYMBOLICÚ	FF_SCRIPTÚFF_NONSYMBOLICrž   Ú	FF_ALLCAPÚFF_SMALLCAPrœ   r   r.   r/   r0   r1   r2   r´   r*   r   r   r   r   Ú<module>   s:    7ÿ! L!
ÿ