
    Q?h94                         S r SrSSKrSSKrSSKrSSKJr  SSKJr  SSK	J
r  SSKJrJr  S r/ S	QrS
rSrSrSrSrSrSrSrSr " S S5      rSSKJrJrJrJr   " S S5      rS r \!S:X  a  \ " 5         gg)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)md5)	quoteattr)process_time)asBytesasNativec                 <     [        U 5      $ !   [        U SS9s $ = f)Nzlatin-1enc)	_asNative)ss    J/var/www/html/env/lib/python3.13/site-packages/reportlab/lib/fontfinder.pyr   r   C   s%    *|*y))s   
 )z.ttfz.ttcz.otfz.pfbz.pfa                @   i   i   i   c                   *    \ rS rSrSrS rS rS rSrg)FontDescriptorV   z{This is a short descriptive record about a font.

typeCode should be a file extension e.g. ['ttf','ttc','otf','pfb','pfa']
c                     S U l         S U l        S U l        S U l        SU l        SU l        SU l        SU l        S U l        S U l	        S U l
        SU l        g )NFr   )namefullName
familyName	styleNameisBoldisItalicisFixedPitch
isSymbolictypeCodefileNamemetricsFileNametimeModifiedselfs    r   __init__FontDescriptor.__init__[   sY    	!#    c                      SU R                   -  $ )NzFontDescriptor(%s))r   r$   s    r   __repr__FontDescriptor.__repr__k   s    #dii//r(   c           
          / nU R                   R                  5        H@  u  p#US;  d  M  U(       d  M  UR                  U< S[        [	        U5      5      < 35        MB     SSR                  U5      -   S-   $ )z Return an XML tag representation)r#   =z<font  z/>)__dict__itemsappendr   strjoin)r%   attrskvs       r   getTagFontDescriptor.getTagn   sb    MM'')DA((1LLAyQ/@!AB * #((5/)D00r(   )r   r!   r   r   r   r   r   r"   r   r   r#   r    N)	__name__
__module____qualname____firstlineno____doc__r&   r*   r7   __static_attributes__ r(   r   r   r   V   s     01r(   r   )rl_isdir	rl_isfile
rl_listdirrl_getmtimec                   x    \ rS rSr/ SSSSS4S jrSS jrSS jrS	 rS
 rS r	S r
SS jrS rS rS rS rSrg)
FontFinderx   TFNr   c                    X l         X0l        Uc  [        R                  " 5       nU=(       d    SU l        [        5       U l        X@l        U R                  U5        / U l	        / U l
        / U l        0 U l        0 U l        0 U l        X`l        g )Nutf8)useCachevalidatesysgetfilesystemencoding_fsEncodingset_dirs_recuraddDirectories_fonts_skippedFiles	_badFiles_fontsByName_fontsByFamily_fontsByFamilyBoldItalicverbose)r%   dirsrI   rJ   recur
fsEncodingrX   s          r   r&   FontFinder.__init__y   s|      224J%/U
D! (*%r(   c                 Z   [        U5      (       a  U R                  R                  U5        Ub  U(       au  OU R                  (       ab  [        R
                  " U5       HG  u  p4nU H;  nU R                  R                  [        R                  R                  X65      5        M=     MI     g g g g N)r@   rO   addrP   oswalkpathr3   )r%   dirNamerZ   rDFds          r   addDirectoryFontFinder.addDirectory   sw     GJJNN7#)ut{{WWW-EA

rww||A'89  . 0;u r(   c                 4    U H  nU R                  X2S9  M     g )N)rZ   )rh   )r%   dirNamesrZ   rc   s       r   rQ   FontFinder.addDirectories   s    Gg2  r(   c                   ^ U R                   (       de  U R                  nU HS  nUR                  nUc  M  X0R                   ;   a   U R                   U   R                  U5        MC  U/U R                   U'   MU     U R                  m[        U4S jU R                   R                  5        5       5      nUR                  5         U$ )z2Returns a list of the distinct font families foundc              3   8   >#    U  H  n[        UTS 9v   M     g7fr	   Nr   .0_r[   s     r   	<genexpr>,FontFinder.getFamilyNames.<locals>.<genexpr>   s     S8R1WQ:.8R   )rV   rR   r   r1   rM   listkeyssort)r%   fontsfontfamnamesr[   s        @r   getFamilyNamesFontFinder.getFamilyNames   s    ""KKEoo;---'',33D904vD'',  %%
S8K8K8P8P8RSS

r(   c                 :    U R                   R                  U/ 5      $ )z5Return list of all font objects with this family name)rV   get)r%   r   s     r   getFontsInFamilyFontFinder.getFontsInFamily   s    ""&&z"55r(   c           	      "   / nUR                  S5        UR                  S5        U R                   H)  nUR                  S[        [        U5      5      -  5        M+     U R	                  5        H}  nU(       d  M  UR                  S[        [        U5      5      -  5        U R                  U5       H%  nUR                  SUR                  5       -   5        M'     UR                  S5        M     UR                  S5        SR                  U5      $ )	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>
)r1   rO   r   r   r~   r   r7   r3   )r%   linesrc   r   r{   s        r   getFamilyXmlReportFontFinder.getFamilyXmlReport   s     NO&'zzGLL3i@Q6RRS "--/Jz3i@T6UUV 11*=DLLdkkm!;< >_- 0 	'(yyr(   c                     / nU R                    HL  nSnUR                  5        H  u  pV[        X5S5      U:w  d  M  SnM     U(       d  M;  UR                  U5        MN     U$ )z%This is a general lightweight search.TNF)rR   r0   getattrr1   )r%   kwdsselectedr{   OKr5   r6   s          r   getFontsWithAttributes!FontFinder.getFontsWithAttributes   sZ    KKDB

4D)Q.B % r%   r(   c                     U R                    H;  nUR                  U:X  d  M  UR                  U:X  d  M'  UR                  U:X  d  M9  Us  $    [	        SU< SU< SU< 35      e)z$Try to find a font matching the speczCannot find font z with bold=z	, italic=)rR   r   r   r   KeyError)r%   r   bolditalicr{   s        r   getFontFontFinder.getFont   sQ     KKD*,;;$&}}.#	   
TXZ`abbr(   c                    ^ U R                   m[        SR                  U4S j[        U R                  5       5       5      5      R                  5       nSSKJn  U" SU-  5      nU$ )zMBase this on the directories...same set of directories
should give same cacher(   c              3   8   >#    U  H  n[        UTS 9v   M     g7fro   rp   rq   s     r   rt   /FontFinder._getCacheFileName.<locals>.<genexpr>   s     R?Q!GA*5?Qrv   r   )get_rl_tempfilezfonts_%s.dat)rM   r   r3   sortedrO   	hexdigestreportlab.lib.utilsr   )r%   hashr   fnr[   s       @r   _getCacheFileNameFontFinder._getCacheFileName   sR     %%
388Rvdjj?QRRS]]_7^d23	r(   c                 h    [        US5      n[        R                  " X5        UR                  5         g )Nwb)openpickledumpclose)r%   r!   fs      r   saveFontFinder.save   s#    4 D		r(   c                     [        US5      n[        R                  " U5      nUR                  5         U R                  R                  UR                  5        g )Nrb)r   r   loadr   r/   update)r%   r!   r   finder2s       r   r   FontFinder.load   s<    4 ++a.		W--.r(   c           	      4
   U R                   (       a
  [        5       nU R                  (       d  [        S5      eU R                  (       af  U R                  5       n[        U5      (       aF   U R                  U5        U R                   S:  a#  [        S[        U R                  5      U4-  5        g U R                   GHo  n [        U5      nU GHX  n[        R                  R                  U5      u  pgUR                  5       [         ;   d  M?  [#        5       n[        R                  R%                  [        R                  R'                  X55      5      =Ul        n [+        U5      Ul        UR                  5       nUS   S:X  a  USS  nXxl        US;   a  U R.                  R1                  U5        GOYUS;   a  SS	KJn	Jn
   U	" XPR:                  S
9nUR>                  Ul        UR@                  Ul         URB                  Ul!        URD                  Ul"        [F        [F        URH                  -  :H  Ul%        [L        [L        URH                  -  :H  Ul'        GOUS:X  Ga  [        [        R                  R'                  X6S-   5      5      (       aE  [        R                  R%                  [        R                  R'                  X6S-   5      5      Ul(        O[        [        R                  R'                  X6S-   5      5      (       aE  [        R                  R%                  [        R                  R'                  X6S-   5      5      Ul(        OU R.                  R1                  U5        GM  SSK)J*n  U" URP                  5      u  pUS   Ul        URW                  SUR>                  5      Ul         URW                  SS 5      Ul"        [Y        URW                  SS5      5      S:  Ul'        SURW                  SS5      R                  5       ;   Ul%        U R                  R1                  U5        GM[     GMr     U R                  (       a  U R[                  W5        U R                   (       aY  [        5       n[        S[        U R                  5      [        U R.                  5      [        U R<                  5      UW-
  4-  5        g g !    GN= f!    GM  = f!   U R.                  R1                  U5         GM!  = f! U
 a     U R<                  R1                  U5         GMI  f = f)NzbFont search path is empty!  Please specify search directories using addDirectory or addDirectories   z%loaded cached file with %d fonts (%s)r   .r   )otfpfa)ttfttc)
TTFontFileTTFError)rJ   pfbz.afmz.AFM)parseAFMFileFontNameFullName
FamilyNameItalicAngleg        r   Weight z7found %d fonts; skipped %d; bad %d.  Took %0.2f seconds).rX   clockrO   
ValueErrorrI   r   rA   r   printlenrR   rB   r`   rb   splitextlower
EXTENSIONSr   normpathr3   r!   rC   r#   rS   r1   r    reportlab.pdfbase.ttfontsr   r   rJ   rT   r   r   r   r   FF_FORCEBOLDflagsr   	FF_ITALICr   r"   reportlab.pdfbase.pdfmetricsr   r   floatr   )r%   startedcfnrc   	fileNamesr!   rootextr   r   r   r{   r   infoglyphsfinisheds                   r   searchFontFinder.search   s   <<gGzz  B  C  C==((*C~~IIcN||QET[[IY[^H__` zzG&w/	 &GG,,X6	99;*,&(A,.GG,<,<RWW\\'=\,]]AJ!)4X)>
 ))+C1v}!!"g!$J
 n,**11(;-R%#-h#ND "&%)]]
&*nn'+$0L4::4M$M&/9tzz3I&I
 %RWW\\'&=%IJJ020@0@g^dWdAe0fA-&rww||GF]'KLL020@0@g^dWdAe0fA- ..55h?$M)5a6G6G)H!%j!1%)XXj!&&%A
'+xxd'C&+DHH]A,F&G#&M
$*dhhx.C.I.I.K$KKK&&q)u & "@ ==IIcN<<wHKDKK #d&8&8"93t~~;N7"O   M
!**11(; $  ( % NN11(;$%s7   *AR<  SS S1<SS
S.1!TT)rT   rO   rR   rV   rW   rU   rM   rP   rS   rI   rJ   rX   r^   )FF)r9   r:   r;   r<   r&   rh   rQ   r~   r   r   r   r   r   r   r   r   r>   r?   r(   r   rE   rE   x   sO    UW[ef (:3 6 "
	c
/Yr(   rE   c                  ~   SSK Jn   [        U R                  S9nSUl        SUl        SS K nUR                  S5        [        R                  R                  [        R                  R                  UR                  5      S5      nUR                  U5        UR                  5         [        S5        [        UR                  5       5        [        S5        UR                  5        H  n[        S	U-  5        M     [        5         [         R"                  R$                  nU" S
5        UR'                  S5       H  nU" SUR(                  -  5        M     [        5         U" S5        UR+                  SSS9 H  nU" UR,                  S-   5        M     [        5         [        S5        [        UR/                  5       5        g )Nr   )	rl_config)rX   TzC:\windows\fontsrz   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   rE   rX   rI   rJ   rh   r`   rb   r3   dirname__file__r   r   r   r~   rK   stdoutwriter   r   r   r   r   )r   ffr   	rlFontDirr   outwr{   s          r   testr   F  sO   #	I--	.BBKBKOO()RWW__Y-?-?@'JIOOIIIK	
	"


 !	-'')
fz!" * 
G::D	##$9:UTYY ;	G	)))FT]]3 G	G	/	"


!"r(   __main__)"__version__r=   rK   r`   r   hashlibr   xml.sax.saxutilsr   timer   r   r   r   r   r   r   FF_FIXEDFF_SERIFFF_SYMBOLIC	FF_SCRIPTFF_NONSYMBOLICr   	FF_ALLCAPFF_SMALLCAPr   r   r@   rA   rB   rC   rE   r   r9   r?   r(   r   <module>r      s    6	n    & & >* 2
 			1 1B M LL L\#B ZF r(   