o
    0j#A                  
   @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	Z
d dlZd dlmZmZmZ ddlmZ ddlmZmZ ddlmZ ddlmZ d	d
lmZmZ edr\d dlZedrjd dlZd	dlmZ G dd deZ de!de!fddZ"de!de!fddZ#de!de!ddfddZ$	d5de!de!de%dee% fddZ&edd e
j'deee(  fd!d"Z)eddd5d#e!d$e!d%e%fd&d'Z*	d5d(e+d)e,de!de%fd*d+Z-de%fd,d-Z.edd(e+d)e,d.e!d/e!fd0d1Z/d.e!d2e+d/e!dej0fd3d4Z1dS )6    N)ListOptional)Image	ImageDraw	ImageFont   )logging)function_requires_depsis_dep_available)custom_open)PINGFANG_FONT   )BaseCVResult	JsonMixinzopencv-contrib-python	pypdfium2)pdfium_lockc                   @   s,   e Zd Zdd Zdd ZdejfddZdS )	FormulaRecResultc                 O   s8   t | }|d tj|g|R i |d }d|iS )N	input_imgres)copydeepcopypopr   _to_str)selfargskwargsdata_str r   t/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddlex/inference/models/formula_recognition/result.pyr   *   s   

zFormulaRecResult._to_strc                 O   s,   t | }|d tj|g|R i |S )Nr   )r   r   r   r   _to_json)r   r   r   r   r   r   r   r    0   s   

zFormulaRecResult._to_jsonreturnc              
   C   s  t | d }zt  W n tjy( } ztd d|iW  Y d}~S d}~ww t| d }t	|
d}t|}|durS|\}}}}|||| ||| f }t |}|j\}	}
ddg|	dg|	|
gd|
gg}zNt|j||dd	}t |}|j\}}|}t||	 |
 }|||ft j}|jt| d
 }t d||fd}||d |||jd
 df d|iW S  tjy } ztd d|iW  Y d}~S d}~ww )a  
        Draws a recognized formula on an image.

        This method processes an input image to recognize and render a LaTeX formula.
        It overlays the rendered formula onto the input image and returns the combined image.
        If the LaTeX rendering engine is not installed or a syntax error is detected,
        it logs a warning and returns the original image.

        Returns:
            Image.Image: An image with the recognized formula rendered alongside the original image.
        r   zPlease refer to 2.3 Formula Recognition Pipeline Visualization in Formula Recognition Pipeline Tutorial to install the LaTeX rendering engine at first.r   Nrec_formulaRGBr   F)is_debug
      r'   r'   )r   r   z3Syntax error detected in formula, rendering failed.)r   Z	fromarray	env_valid
subprocessCalledProcessErrorr   warningstrnparrayconvertcrop_white_areasizedraw_formula_moduleintresizeZLANCZOSwidthnewZpaste)r   imageer"   xywhxywhZimage_widthZimage_heightboxZimg_formularender_widthrender_heightZresize_heightZresize_widthZnew_image_widthZ	new_imager   r   r   _to_img5   sP   








zFormulaRecResult._to_imgN)__name__
__module____qualname__r   r    r   rA   r   r   r   r   r   (   s    r   equationr!   c                 C   sV   d}t | d } ddg}|D ]
}|| v rd} nq|s)d|   d d d d } | S )	a  
    Wraps an equation in LaTeX environment tags if not already aligned.

    This function checks if a given LaTeX equation contains any alignment tags (`align` or `align*`).
    If the equation does not contain these tags, it wraps the equation in `equation` and `nonumber` tags.

    Args:
        equation (str): The LaTeX equation to be checked and potentially modified.

    Returns:
        str: The modified equation with appropriate LaTeX tags for alignment.
    F
zbegin{align}zbegin{align*}Tz\begin{equation}
z	\nonumberz\end{equation})r,   strip)rE   Zis_align
begin_dictZ	begin_symr   r   r   get_align_equationk   s0   	rI   formulac                 C   s"   t d}dd }||| }|S )Nz([^\x00-\x7F]+)c                 S   s   d|  d dS )Nz\text{   })group)matchr   r   r   replacer   s   z)add_text_for_zh_formula.<locals>.replacer)recompilesub)rJ   patternrO   Zreplaced_formular   r   r   add_text_for_zh_formula   s   
rT   tex_file_pathc                 C   sf   t | d$}d}|| t|}t|}|| d}|| W d   dS 1 s,w   Y  dS )a  
    Generates a LaTeX file containing a specific equation.

    This function creates a LaTeX file at the specified file path, writing the necessary
    LaTeX preamble and wrapping the provided equation in a document structure. The equation
    is processed to ensure it includes alignment tags if necessary.

    Args:
        tex_file_path (str): The file path where the LaTeX file will be saved.
        equation (str): The LaTeX equation to be written into the file.
    r<   a  
            \documentclass[varwidth]{standalone}
            \usepackage{cite}
            \usepackage{amsmath,amssymb,amsfonts,upgreek}
            \usepackage{graphicx}
            \usepackage{textcomp}
            \usepackage{xeCJK}
            \DeclareMathSizes{14}{14}{9.8}{7}
            \pagestyle{empty}
            \makeatletter
            \def\x@arrow{\DOTSB\Relbar}
            \def\xlongequalsignfill@{\arrowfill@\x@arrow\Relbar\x@arrow}
            \newcommand{\xlongequal}[2][]{\ext@arrow 0099\xlongequalsignfill@{#1}{#2}}
            \def\xLongleftrightarrowfill@{\arrowfill@\Longleftarrow\Relbar\Longrightarrow}
            \newcommand{\xLongleftrightarrow}[2][]{\ext@arrow 0099\xLongleftrightarrowfill@{#1}{#2}}
            \def\xlongleftrightarrowfill@{\arrowfill@\longleftarrow\relbar\longrightarrow}
            \newcommand{\xlongleftrightarrow}[2][]{\ext@arrow 0099\xlongleftrightarrowfill@{#1}{#2}}
            \def\xLeftrightarrowfill@{\arrowfill@\Leftarrow\Relbar\Rightarrow}
            \newcommand{\xLeftrightarrow}[2][]{\ext@arrow 0099\xLeftrightarrowfill@{#1}{#2}}
            \def\xleftrightarrowfill@{\arrowfill@\leftarrow\relbar\rightarrow}
            \newcommand{\xleftrightarrow}[2][]{\ext@arrow 0099\xleftrightarrowfill@{#1}{#2}}
            \def\xLongleftarrowfill@{\arrowfill@\Longleftarrow\Relbar\Relbar}
            \newcommand{\xLongleftarrow}[2][]{\ext@arrow 0099\xLongleftarrowfill@{#1}{#2}}
            \def\xLongrightarrowfill@{\arrowfill@\Relbar\Relbar\Longrightarrow}
            \newcommand{\xLongrightarrow}[2][]{\ext@arrow 0099\xLongrightarrowfill@{#1}{#2}}
            \def\xlongleftarrowfill@{\arrowfill@\longleftarrow\relbar\relbar}
            \newcommand{\xlongleftarrow}[2][]{\ext@arrow 0099\xlongleftarrowfill@{#1}{#2}}
            \def\xlongrightarrowfill@{\arrowfill@\relbar\relbar\longrightarrow}
            \newcommand{\xlongrightarrow}[2][]{\ext@arrow 0099\xlongrightarrowfill@{#1}{#2}}
            \makeatother
            \begin{document}
            \begin{large}
        z\end{large}
\end{document}
N)r   writerT   rI   )rU   rE   fpZstart_templateZend_templater   r   r   generate_tex_file   s   
!
"rX   Ftex_pathpdf_dirr$   c                 C   sX   t j| r*d|| }|rtj|dd dS tt jd tj|tjtj	dd dS dS )a  
    Generates a PDF file from a LaTeX file using pdflatex.

    This function checks if the specified LaTeX file exists, and then runs pdflatex to generate a PDF file
    in the specified directory. It can run in debug mode to show detailed output or in silent mode.

    Args:
        tex_path (str): The path to the LaTeX file.
        pdf_dir (str): The directory where the PDF file will be saved.
        is_debug (bool, optional): If True, runs pdflatex with detailed output. Defaults to False.

    Returns:
        Optional[bool]: Returns True if the PDF was generated successfully, False if the LaTeX file does not exist,
                        and None if an error occurred during the pdflatex execution.
    zGxelatex -interaction=nonstopmode -halt-on-error -output-directory={} {}T)shellr<   )stdoutstderrr[   N)
ospathexistsformatr)   
check_callr   devnullPIPESTDOUT)rY   rZ   r$   commandr   r   r   generate_pdf_file   s   
rg   r7   c           	      C   s~   t | d} t| tj}t|ddtj\}}t|tj	tj
\}}t|dkr=tt |\}}}}||||gS dS )a  
    Finds and returns the bounding box of the non-white area in an image.

    This function converts an image to grayscale and uses binary thresholding to
    find contours. It then calculates the bounding rectangle around the non-white
    areas of the image.

    Args:
        image (np.ndarray): The input image as a NumPy array.

    Returns:
        Optional[List[int]]: A list [x, y, w, h] representing the bounding box of
                             the non-white area, or None if no such area is found.
    uint8   r'   r   N)r-   r.   Zastypecv2ZcvtColorZCOLOR_BGR2GRAY	thresholdZTHRESH_BINARY_INVZfindContoursZRETR_EXTERNALZCHAIN_APPROX_SIMPLElenZboundingRectZconcatenate)	r7   gray_ZthreshZcontoursr:   r;   r<   r=   r   r   r   r0      s   r0   pdf_pathimg_path
is_paddingc                 C   s  t  t| }zlt|dkrW |  W d   dS |D ]P}td}d}|j||d }|  t|}|durn|\}	}
}}||
|
| |	|	| f }|r^t	j
|ddddt	jdd}|  W |  W  d   S qW |  n|  w W d   dS 1 sw   Y  dS )	a  
    Converts a single-page PDF to an image, optionally cropping white areas and adding padding.

    Args:
        pdf_path (str): The path to the PDF file.
        img_path (str): The path where the image will be saved.
        is_padding (bool): If True, adds a 30-pixel white padding around the image.

    Returns:
        np.ndarray: The resulting image as a NumPy array, or None if the PDF is not single-page.
    rK   Nr      )scaleZrotation   r&   )value)r   pdfiumZPdfDocumentrl   closer3   renderZto_numpyr0   rj   ZcopyMakeBorderBORDER_CONSTANT)ro   rp   rq   ZpdfDocpagerotateZzoomZimgr9   r:   r;   r<   r=   r   r   r   pdf2img  s<   

r|   img_sizer>   c                 C   s   | \}}t  T}tj|d}tj|d}tj|d}	t|| tj|r/t||| d}
tj|r>t||	dd}
|
durK|
W  d   S t	| |dt
j}|W  d   S 1 s_w   Y  dS )a  
    Draw box formula for module.

    Args:
        img_size (tuple): The size of the image as (width, height).
        box (list): The coordinates for the bounding box.
        formula (str): The LaTeX formula to render.
        is_debug (bool): If True, retains intermediate files for debugging purposes.

    Returns:
        np.ndarray: The resulting image with the formula or an error message.
    temp.textemp.pdftemp.jpgNFrq   zRendering Failed)tempfileTemporaryDirectoryr^   r_   joinrX   r`   rg   r|   draw_box_txt_finer   )r}   r>   rJ   r$   	box_width
box_heighttdrU   pdf_file_pathimg_file_pathformula_imgimg_right_textr   r   r   r2   1  s&   


$r2   c                  C   s   t  H} tj| d}tj| d}tj| d}d}d}t|| tj|r/t|| | tj|rDt||dd}W d   dS W d   dS 1 sOw   Y  dS )z
    Validates if the environment is correctly set up to convert LaTeX formulas to images.

    Returns:
        bool: True if the environment is valid and the conversion is successful, False otherwise.
    r~   r   r   za+b=cFr   N)	r   r   r^   r_   r   rX   r`   rg   r|   )r   rU   r   r   rJ   r$   r   r   r   r   r(   T  s   

	"r(   txt	font_pathc                 C   s  t t|d d |d d  d |d d |d d  d  }t t|d d |d d  d |d d |d d  d  }|d| krv|dkrvtd||fd}t|}|rot|||f|}|jddg|d|d	 |	tj
}n#td||fd}t|}|rt|||f|}|jddg|d|d	 tddg|dg||gd|gg}	tj|tjd
}
t|	|
}tj|tjd
}tj||| tjtjdd}|S )a  
    Draw box text.

    Args:
        img_size (tuple): Size of the image as (width, height).
        box (list): List of four points defining the box, each point is a tuple (x, y).
        txt (str): The text to draw inside the box.
        font_path (str): Path to the font file to be used for drawing text.

    Returns:
        np.ndarray: Image array with the text drawn and transformed to fit the box.
    r   r   rr   rK   rt   r#   r&   )r   r   r   )fillfont)Zdtype)flagsZ
borderModeZborderValue)r3   mathsqrtr   r6   r   ZDrawcreate_fonttextZ	transposeZ
ROTATE_270r-   Zfloat32r.   rj   ZgetPerspectiveTransformrh   ZwarpPerspectiveZINTER_NEARESTry   )r}   r>   r   r   r   r   Zimg_textZ	draw_textr   Zpts1Zpts2Mr   r   r   r   r   h  sB   <<

r   szc                 C   s   t |d d }tj||dd}t tjdd dk r$|| d }n|| }||d krAt ||d  | }tj||dd}|S )a[  
    Creates a font object with a size that ensures the text fits within the specified dimensions.

    Args:
        txt (str): The text to fit.
        sz (tuple): The target size as (width, height).
        font_path (str): The path to the font file.

    Returns:
        ImageFont.FreeTypeFont: A PIL font object at the appropriate size.
    rK   g?zutf-8)encoding.r   r%   )r3   r   ZtruetypePIL__version__splitgetsizeZ	getlength)r   r   r   Z	font_sizer   lengthr   r   r   r     s   
r   )F)2r   r   r^   rP   r)   r   typingr   r   numpyr-   r   r   r   r   utilsr   Z
utils.depsr	   r
   Zutils.file_interfacer   Zutils.fontsr   Zcommon.resultr   r   rj   r   rv   Zutils.pdfium_lockr   r   r,   rI   rT   rX   boolrg   Zndarrayr3   r0   r|   tuplelistr2   r(   r   ZFreeTypeFontr   r   r   r   r   <module>   sh   C%7
&
# 4