
    j5jS                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	  ej                  e      Z G d de      Z G d	 d
      Z G d d      Zy)z=Font provider protocol and implementations for PDF rendering.    )annotationsN)Path)Protocol)FontManagerc                  (    e Zd ZdZddZddZddZy)	FontProviderzProtocol for providing fonts to MultiFontManager.

    Implementations are responsible for knowing where fonts are located
    and loading them. MultiFontManager asks for fonts by name and uses
    them for glyph coverage checking.
    c                     y)zGet a FontManager for the named font.

        Args:
            font_name: Logical font name (e.g., 'NotoSans-Regular')

        Returns:
            FontManager if font is available, None otherwise
        N self	font_names     Q/var/www/html/qr/venv/lib/python3.12/site-packages/ocrmypdf/font/font_provider.pyget_fontzFontProvider.get_font   s     	    c                     y)zGet list of available font names.

        Returns:
            List of font names that can be retrieved with get_font()
        Nr
   r   s    r   get_available_fontsz FontProvider.get_available_fonts$   s     	r   c                     y)zGet the glyphless fallback font.

        This font must always be available and handles any codepoint.

        Returns:
            FontManager for the glyphless fallback font (Occulta.ttf)
        Nr
   r   s    r   get_fallback_fontzFontProvider.get_fallback_font,   s     	r   Nr   strreturnzFontManager | Noner   z	list[str]r   r   )__name__
__module____qualname____doc__r   r   r   r
   r   r   r   r      s    	r   r   c                  D    e Zd ZdZdddZdddZddZddZdd	Zdd
Z	y)BuiltinFontProviderz?Font provider using builtin fonts from ocrmypdf/data directory.zNotoSans-Regular.ttfzOcculta.ttf)zNotoSans-RegularOccultaNc                    |&t        t              j                  j                  dz  }|| _        i | _        | j                          y)zInitialize builtin font provider.

        Args:
            font_dir: Directory containing font files. If None, uses
                      the default ocrmypdf/data directory.
        Ndata)r   __file__parentfont_dir_fonts_load_fonts)r   r&   s     r   __init__zBuiltinFontProvider.__init__C   s>     H~,,33f<H .0r   c                   | j                   j                         D ]h  \  }}| j                  |z  }|j                         s+|dk(  rt	        d|       t
        j                  d||       P	 t        |      | j                  |<   j y# t        $ r8}|dk(  rt        d| d|       |t
        j                  d||       Y d}~d}~ww xY w)z8Load available fonts, logging warnings for missing ones.r!   z"Required fallback font not found: zMFont %s not found at %s - OCR output quality for some scripts may be affectedz&Failed to load required fallback font z: z?Failed to load font %s: %s - OCR output quality may be affectedN)
FONT_FILESitemsr&   existsFileNotFoundErrorlogwarningr   r'   	Exception
ValueError)r   r   	font_file	font_pathes        r   r(   zBuiltinFontProvider._load_fontsP   s    $(OO$9$9$; 	 Iy	1I##%	)+<YKH  .	 )4Y)?I&!	"  		)$@2aSQ U 	s   ,B	C.CCc                8    | j                   j                  |      S )z%Get a FontManager for the named font.)r'   getr   s     r   r   zBuiltinFontProvider.get_fontn   s    {{y))r   c                H    t        | j                  j                               S )z!Get list of available font names.)listr'   keysr   s    r   r   z'BuiltinFontProvider.get_available_fontsr   s    DKK$$&''r   c                     | j                   d   S )z Get the glyphless fallback font.r!   )r'   r   s    r   r   z%BuiltinFontProvider.get_fallback_fontv   s    {{9%%r   )N)r&   zPath | None)r   Noner   r   r   )
r   r   r   r   r+   r)   r(   r   r   r   r
   r   r   r    r    7   s-    I 3 J
<*(&r   r    c                  0    e Zd ZdZddZddZd	dZd
dZy)ChainedFontProviderzFont provider that tries multiple providers in order.

    This allows combining builtin fonts with system fonts, trying
    the builtin provider first and falling back to system fonts
    for fonts not bundled with the package.
    c                ,    |st        d      || _        y)zInitialize chained font provider.

        Args:
            providers: List of font providers to try in order.
                       The first provider that returns a font wins.
        z!At least one provider is requiredN)r2   	providers)r   r@   s     r   r)   zChainedFontProvider.__init__   s     @AA"r   c                T    | j                   D ]  }|j                  |      x}s|c S  y)a  Get a FontManager for the named font.

        Tries each provider in order until one returns a font.

        Args:
            font_name: Logical font name (e.g., 'NotoSans-Regular')

        Returns:
            FontManager if any provider has the font, None otherwise
        N)r@   r   )r   r   providerfonts       r   r   zChainedFontProvider.get_font   s7      	H((33t3	 r   c                    t               }g }| j                  D ]>  }|j                         D ])  }||vs|j                  |       |j	                  |       + @ |S )zGet list of available font names from all providers.

        Returns:
            Combined list of font names (deduplicated, order preserved)
        )setr@   r   addappend)r   seenresultrB   names        r   r   z'ChainedFontProvider.get_available_fonts   sa      	(H 446 (t#HHTNMM$'(	(
 r   c                    | j                   D ]  }	 |j                         c S  t        d      # t        t        t        f$ r Y 8w xY w)a   Get the glyphless fallback font.

        Tries each provider until one provides a fallback font.

        Returns:
            FontManager for the fallback font

        Raises:
            RuntimeError: If no provider can provide a fallback font
        z,No fallback font available from any provider)r@   r   NotImplementedErrorAttributeErrorKeyErrorRuntimeError)r   rB   s     r   r   z%ChainedFontProvider.get_fallback_font   sT      	H1133	
 IJJ (B s   /AAN)r@   zlist[FontProvider]r   r   r   )r   r   r   r   r)   r   r   r   r
   r   r   r>   r>   {   s    	# Kr   r>   )r   
__future__r   loggingpathlibr   typingr   ocrmypdf.font.font_managerr   	getLoggerr   r/   r   r    r>   r
   r   r   <module>rV      sT    D "    2g!#8 #LA& A&HBK BKr   