
    j5j                         d Z ddlmZ ddlmZmZ ddlmZ e G d d             Ze G d d             Z	e G d	 d
             Z
e G d d             Zed   Z G d d      Zy)a)  OCR element dataclasses for representing OCR output structure.

This module provides a generic, engine-agnostic representation of OCR output.
The OcrElement dataclass can represent structural units from any OCR source
(hOCR, ALTO, custom engines, etc.) in a unified format suitable for rendering.
    )annotations)	dataclassfield)Literalc                  d    e Zd ZU dZded<   ded<   ded<   ded<   edd       Zedd       Zd	 Zy
)BoundingBoxa%  An axis-aligned bounding box in pixel coordinates.

    Coordinates use top-left origin (standard for images and hOCR).

    Attributes:
        left: Left edge x-coordinate
        top: Top edge y-coordinate
        right: Right edge x-coordinate
        bottom: Bottom edge y-coordinate
    floatlefttoprightbottomc                4    | j                   | j                  z
  S )zWidth of the bounding box.)r   r
   selfs    Q/var/www/html/qr/venv/lib/python3.12/site-packages/ocrmypdf/models/ocr_element.pywidthzBoundingBox.width#   s     zzDII%%    c                4    | j                   | j                  z
  S )zHeight of the bounding box.)r   r   r   s    r   heightzBoundingBox.height(   s     {{TXX%%r   c                    | j                   | j                  k  r&t        d| j                    d| j                   d      | j                  | j                  k  r&t        d| j                   d| j                   d      y)z"Validate bounding box coordinates.zInvalid bounding box: right (z
) < left ()zInvalid bounding box: bottom (z	) < top (N)r   r
   
ValueErrorr   r   r   s    r   __post_init__zBoundingBox.__post_init__-   sy    ::		!/

|:dii[PQR  ;;!0YtxxjPQR  "r   N)returnr	   )	__name__
__module____qualname____doc____annotations__propertyr   r   r    r   r   r   r      sH    	 K	JLM& & & &	r   r   c                  .    e Zd ZU dZdZded<   dZded<   y)Baselineak  Text baseline information.

    The baseline is represented as a linear equation: y = slope * x + intercept.
    This describes the line along which text characters sit, relative to the
    bottom-left corner of the line's bounding box.

    In hOCR, the baseline is specified relative to the bottom of the line's bbox,
    with the intercept being the vertical offset from the bottom and the slope
    representing rotation (positive = ascending left-to-right).

    Attributes:
        slope: Slope of the baseline (rise over run)
        intercept: Y-intercept of the baseline (vertical offset from bbox bottom)
    g        r	   slope	interceptN)r   r   r   r   r$   r   r%   r!   r   r   r#   r#   9   s     E5Iur   r#   c                      e Zd ZU dZdZded<   dZded<   dZded	<   dZded
<   dZ	ded<   dZ
ded<   dZded<   dZded<   y)FontInfoa  Font information for text rendering.

    Attributes:
        name: Font family name (e.g., "Times New Roman")
        size: Font size in points
        bold: Whether the font is bold
        italic: Whether the font is italic
        monospace: Whether the font is monospace
        serif: Whether the font is serif (vs sans-serif)
        smallcaps: Whether the font uses small caps
        underline: Whether the text is underlined
    N
str | Nonenamefloat | NonesizeFboolbolditalic	monospaceserif	smallcaps	underline)r   r   r   r   r)   r   r+   r-   r.   r/   r0   r1   r2   r!   r   r   r'   r'   N   sY     D*D,D$FDItE4ItItr   r'   c                  .   e Zd ZU dZded<   dZded<   dZded<   d	Zded
<   dZded<    e	e
      Zded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   d#dZd$dZd%dZed&d        Zed&d!       Zed&d"       Zy)'
OcrElementa  A generic OCR element representing any structural unit of OCR output.

    OcrElements form a tree structure where pages contain paragraphs, paragraphs
    contain lines, lines contain words, etc. The specific hierarchy depends on
    the OCR engine, but this dataclass can represent any of these levels.

    The ocr_class field uses hOCR naming conventions (ocr_page, ocr_par, ocr_line,
    ocrx_word, etc.) as a common vocabulary, but elements from other sources can
    map to these classes.

    Common hOCR classes:
        - ocr_page: The root element for a page
        - ocr_carea: A content/column area
        - ocr_par: A paragraph
        - ocr_line: A line of text
        - ocr_header: A header line
        - ocr_footer: A footer line
        - ocr_caption: A caption line
        - ocr_textfloat: A floating text element
        - ocrx_word: A single word

    Attributes:
        ocr_class: The element type (e.g., "ocr_page", "ocr_line", "ocrx_word")
        bbox: Axis-aligned bounding box in source pixel coordinates (top-left origin)
        poly: Polygon vertices for oriented/non-rectangular bounds
        text: Text content (primarily for leaf nodes like words)
        confidence: OCR confidence score (0.0-1.0)
        children: Child elements (hierarchical structure)
        direction: Text direction ("ltr" or "rtl")
        language: Language code (e.g., "eng", "deu", "chi_sim")
        baseline: Text baseline information (slope and intercept)
        textangle: Text rotation angle in degrees (counter-clockwise from horizontal)
        font: Font information (name, size, style)
        dpi: Image resolution in dots per inch (typically for page-level)
        page_number: Physical page number (0-indexed)
        logical_page_number: Logical page number (as printed on the page)
    str	ocr_classNzBoundingBox | Nonebboxz list[tuple[float, float]] | Nonepoly textr*   
confidence)default_factorylist[OcrElement]childrenzLiteral['ltr', 'rtl'] | None	directionr(   languagezBaseline | Nonebaseline	textanglezFontInfo | Nonefontdpiz
int | Nonepage_numberlogical_page_numberc                    g }| j                   |v r|j                  |        | j                  D ]   }|j                   |j                  |        " |S )zIterate over all descendants matching the given class(es).

        Args:
            *ocr_classes: One or more ocr_class values to match

        Returns:
            List of all matching descendant elements (depth-first order)
        )r6   appendr>   extenditer_by_class)r   ocr_classesresultchilds       r   rJ   zOcrElement.iter_by_class   sS     >>[(MM$]] 	=EMM-%--{;<	=r   c                p    | j                   |v r| S | j                  D ]  } |j                  | }||c S  y)zFind the first descendant matching the given class(es).

        Args:
            *ocr_classes: One or more ocr_class values to match

        Returns:
            The first matching element, or None if not found
        N)r6   r>   find_by_class)r   rK   rM   rL   s       r   rO   zOcrElement.find_by_class   sJ     >>[(K]] 	E(U((+6F!	 r   c                    | j                   r| j                   S | j                  D cg c]  }|j                          }}dj                  d |D              S c c}w )zGet the combined text of this element and all descendants.

        Returns:
            Combined text content, with words separated by spaces
         c              3  &   K   | ]	  }|s|  y w)Nr!   ).0ts     r   	<genexpr>z0OcrElement.get_text_recursive.<locals>.<genexpr>   s     .aA.s   )r:   r>   get_text_recursivejoin)r   rM   textss      r   rV   zOcrElement.get_text_recursive   sP     99999=G))+GGxx.5... Hs   Ac                $    | j                  d      S )z<Get all word elements (ocrx_word) in this element's subtree.	ocrx_wordrJ   r   s    r   wordszOcrElement.words   s     !!+..r   c                ,    | j                  ddddd      S )z0Get all line elements in this element's subtree.ocr_line
ocr_header
ocr_footerocr_captionocr_textfloatr[   r   s    r   lineszOcrElement.lines   s"     !!lM?
 	
r   c                $    | j                  d      S )z?Get all paragraph elements (ocr_par) in this element's subtree.ocr_parr[   r   s    r   
paragraphszOcrElement.paragraphs   s     !!),,r   )rK   r5   r   r=   )rK   r5   r   zOcrElement | None)r   r5   )r   r=   )r   r   r   r   r   r7   r8   r:   r;   r   listr>   r?   r@   rA   rB   rC   rD   rE   rF   rJ   rO   rV   r    r\   rc   rf   r!   r   r   r4   r4   g   s    $L N  $D
#-1D
*1 D#N  $J# "'t!<H< /3I+2Hj !%Ho$ #I|" !D/  C"K"&** "	/ / / 
 
 - -r   r4   )ltrrtlc                  R    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZ eeee	e
eh      Zy)OcrClassz)Constants for common OCR element classes.ocr_page	ocr_careare   r^   r_   r`   ra   rb   rZ   
ocrx_cinfoN)r   r   r   r   PAGECAREA	PARAGRAPHLINEHEADERFOOTERCAPTION	TEXTFLOATWORDCHAR	frozenset
LINE_TYPESr!   r   r   rk   rk      sX    3 DE I DFFGI D D D&&'9EFJr   rk   N)r   
__future__r   dataclassesr   r   typingr   r   r#   r'   r4   TextDirectionrk   r!   r   r   <module>r      s    # (  $ $ $N   (   0 C- C- C-N %G Gr   