
    khw                        d dl mZmZmZmZmZmZmZ d dlmZ d dl	m	Z	 d dl
mZm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 d	d
lmZmZ d	dlmZmZm Z m!Z!m"Z" d	dl#m$Z$m%Z% d Z&ddddZ'd Z(e' G d de             Z)e' G d de             Z*e' G d de             Z+e)e*e+gZ,e,D  ci c]  } | jZ                  |  c} Z. e/e,      D  ci c]  \  }} | jZ                  | c} }Z0 e'e       G d de             Z1yc c} w c c} }w )    )ListUnionDictr   AnyOptionalTuple)Iterable)copy)
getmembers
isfunctionN)Image)getPerspectiveTransform)warpPerspective   )BaseCoordElementBaseLayoutElement)cvt_coordinates_to_pointscvt_points_to_coordinatesperspective_transformationvertice_in_polygonpolygon_area)NotSupportedShapeErrorInvalidShapeErrorc                 B     t        j                          fd       }|S )Nc                 f     | g|i |}t        |t              rt        |       } || _        | S y N)
isinstancer   r
   block)selfargskwargsoutfuncs       a/var/www/teggl/fontify/venv/lib/python3.12/site-packages/layoutparser/elements/layout_elements.pywrapz"mixin_textblock_meta.<locals>.wrap(   s<    4)$)&)c+,:DDJK -    	functoolswrapsr#   r%   s   ` r$   mixin_textblock_metar+   '   s%    __T  Kr&   
base_classc                `   | t        j                  t        |      S t        | t              D ]}  \  }}|j
                  r|d k(  r>| j                  dd  D ]+  }t        ||      st        ||      j
                  |_         T Vt        ||      sct        ||      j
                  |_         | S )Nr,   r   )	r(   partialinherit_docstringsr   r   __doc____mro__hasattrgetattr)clsr-   namer#   parents        r$   r0   r0   3   s     {  !3
KK j1 
A
d<<++ab/ 64(#*64#8#@#@DL
 z4(&z48@@
A Jr&   c                 B     t        j                          fd       }|S )Nc                 Z    t        |t              r|j                  } | |g|i |}|S r   )r   	TextBlockr   )r   otherr    r!   r"   r#   s        r$   r%   zsupport_textblock.<locals>.wrapI   s1    eY'KKE4000
r&   r'   r*   s   ` r$   support_textblockr<   H   s%    __T  Kr&   c                      e Zd ZdZdZg dZddZed        Zed        Z	ed        Z
ed	        Zed
        Zed        Zd Zed        Zed        Zei dfd       Zeddedefd       Zeddedefd       ZddZd Zd Zd Zd Zd Zy)Intervala  
    This class describes the coordinate system of an interval, a block defined by a pair of start and end point
    on the designated axis and same length as the base canvas on the other axis.

    Args:
        start (:obj:`numeric`):
            The coordinate of the start point on the designated axis.
        end (:obj:`numeric`):
            The end coordinate on the same axis as start.
        axis (:obj:`str`):
            The designated axis that the end points belong to.
        canvas_height (:obj:`numeric`, `optional`, defaults to 0):
            The height of the canvas that the interval is on.
        canvas_width (:obj:`numeric`, `optional`, defaults to 0):
            The width of the canvas that the interval is on.
    intervalstartendaxiscanvas_heightcanvas_widthNc                     ||k  sJ d       || _         || _        |dv sJ d| d       || _        |xs d| _        |xs d| _        y )Nz3Invalid input for start and end. Start must <= end.)xyzInvalid axis z. Axis must be in 'x' or 'y'r   r@   )r   rA   rB   rC   rD   rE   s         r$   __init__zInterval.__init__i   s`    |SRS|
z!U]4&8T#UU!	*/a(-Ar&   c                 j    | j                   dk(  r| j                  S | j                  | j                  z
  S )a-  
        Calculate the height of the interval. If the interval is along the x-axis, the height will be the
        height of the canvas, otherwise, it will be the difference between the start and end point.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        rG   )rC   rD   rB   rA   r   s    r$   heightzInterval.heightu   s/     99%%%88djj((r&   c                 j    | j                   dk(  r| j                  S | j                  | j                  z
  S )a)  
        Calculate the width of the interval. If the interval is along the y-axis, the width will be the
        width of the canvas, otherwise, it will be the difference between the start and end point.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        rH   )rC   rE   rB   rA   rK   s    r$   widthzInterval.width   s/     99$$$88djj((r&   c                     | j                   dk(  r&| j                  d| j                  | j                  f}|S d| j                  | j                  | j                  f}|S )a6  
        This method considers an interval as a rectangle and calculates the coordinates of the upper left
        and lower right corners to define the interval.

        Returns:
            :obj:`Tuple(numeric)`:
                Output the numeric values of the coordinates in a Tuple of size four.
        rG   r   )rC   rA   rB   rD   rE   )r   coordss     r$   coordinateszInterval.coordinates   sV     99jj!TXXt/A/ABF  T%6%6AFr&   c                 ,    t        | j                        S )z
        Return the coordinates of all four corners of the interval in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        r   rQ   rK   s    r$   pointszInterval.points        ))9)9::r&   c                 :    | j                   | j                  z   dz  S )z
        Calculate the mid-point between the start and end point.

        Returns:
            :obj:`Tuple(numeric)`: Returns of coordinate of the center.
               @rA   rB   rK   s    r$   centerzInterval.center   s     

TXX%,,r&   c                 4    | j                   | j                  z  S )a.  Return the area of the covered region of the interval.
        The area is bounded to the canvas. If the interval is put
        on a canvas, the area equals to interval width * canvas height
        (axis='x') or interval height * canvas width (axis='y').
        Otherwise, the area is zero.
        )rL   rN   rK   s    r$   areazInterval.area   s     {{TZZ''r&   c                 4   t        |t        j                        r|j                  dd \  }}nYt        |t              r|j
                  |j                  }}n0t        |t        j                        r|j                  \  }}nt        | j                  ||      S )a  
        Set the height and the width of the canvas that the interval is on.

        Args:
            canvas (:obj:`Numpy array` or :obj:`BaseCoordElement` or :obj:`PIL.Image.Image`):
                The base element that the interval is on. The numpy array should be the
                format of `[height, width]`.

        Returns:
            :obj:`Interval`:
                A copy of the current Interval with its canvas height and width set to
                those of the input canvas.
        N   )rD   rE   )r   npndarrayshaper   rL   rN   r   sizeNotImplementedErrorset)r   canvashws       r$   put_on_canvaszInterval.put_on_canvas   sv     fbjj)<<#DAq 01==&,,qA,;;DAq%%xxaax88r&   c                    t        |t              rg|j                  | j                  k(  rC|j                  }| j	                  | j                  |z   | j
                  |z   | j                        S t        |       S t        |t              r.| j                  |      j                         j                  |      S t        |t              r.| j                  |      j                         j                  |      S t        d|j                   d      NInvalid input type 
 for other)r   r>   rC   rA   	__class__rB   r
   	Rectanglerg   to_rectanglecondition_onQuadrilateralto_quadrilateral	Exceptionr   r;   ds      r$   ro   zInterval.condition_on   s     eX&zzTYY&KK~~djj1ndhhlDIINNDz!y)%%e,99;HHOO}-%%e,==?LLUSS 1%//1B*MNNr&   c                    t        |t              rg|j                  | j                  k(  rC|j                  }| j	                  | j                  |z
  | j
                  |z
  | j                        S t        |       S t        |t              r.| j                  |      j                         j                  |      S t        |t              r.| j                  |      j                         j                  |      S t        d|j                   d      ri   )r   r>   rC   rA   rl   rB   r
   rm   rg   rn   relative_torp   rq   rr   rs   s      r$   rv   zInterval.relative_to   s     eX&zzTYY&KK~~djj1ndhhlDIINNDz!y)%%e,99;GGNN}-%%e,==?KKERR 1%//1B*MNNr&   Fc                 F    |j                   di |}t        |t              r| j                  |j                  k7  ry|s@|j                  | j                  cxk  xr! | j
                  cxk  xr |j
                  k  S c S |j                  | j                  cxk  xr |j
                  k  S c S t        |t              st        |t              r|j                  \  }}}}|rC| j                  dk(  r|| j                  cxk  xr |k  S c S || j                  cxk  xr |k  S c S | j                  dk(  r,|| j                  cxk  xr | j
                  cxk  xr |k  S c S || j                  cxk  xr | j
                  cxk  xr |k  S c S t        d|j                   d      )NFrG   rj   rk    )padr   r>   rC   rA   rB   rY   rm   rp   rQ   rr   rl   )r   r;   soft_marginrY   x_1y_1x_2y_2s           r$   is_inzInterval.is_in  s\    		(K(eX&yyEJJ& ;;$**MMEIIMMMM ;;$++BBBBBy)Z}-M!&!2!2Cc399#$++44444$++4444499#$**??C????$**??C???? 1%//1B*MNNr&   r;   strictc           	         t        |t              r| j                  |j                  k7  r| j                  dk(  rE|j                  dk(  r6t        | j                  |j                  | j
                  |j
                        S t        |j                  | j                  |j
                  | j
                        S | j                  t        | j                  |j                        t        | j
                  |j
                        | j                  | j                  | j                        S t        |t              r|j                  \  }}}}| j                  dk(  r6t        t        || j                        |t        || j
                        |      S | j                  dk(  r6t        |t        || j                        |t        || j
                              S y	t        |t              rV|rt        d      t        j                  d|j                   dt         d       | j!                  |j#                               S t%        d|j                   d      )
 rG   rH     The intersection between an Interval and a Quadrilateral might generate Polygon shapes that are not supported in the current version of layoutparser. You can pass `strict=False` in the input that converts the Quadrilateral to Rectangle to avoid this Exception.(With `strict=False`, the other of shape  will be converted to  for obtaining the intersectionrj   rk   N)r   r>   rC   rm   rA   rB   rl   maxminrD   rE   rQ   rp   r   warningswarn	intersectrn   rr   r   r;   r   r{   r|   r}   r~   s          r$   r   zInterval.intersect+  s    eX&yyEJJ&99#

c(9$TZZdhh		RR$U[[$**eiiRR~~

EKK0%)),II&&%%  y)!&!2!2Cc3yyC S$**!5sCTXX<NPSTTc! c#tzz&:CS$((ASTT " }-, [  >u>OOefoep  qP  Q ~~e&8&8&:;; 1%//1B*MNNr&   c           	         t        |t              r| j                  |j                  k7  rt        d      | j	                  t        | j                  |j                        t        | j                  |j                        | j                  | j                  | j                        S t        |t              r|j                  \  }}}}| j                  dk(  r6t        t        || j                        |t        || j                        |      S | j                  dk(  r6t        |t        || j                        |t        || j                              S y
t        |t              rV|rt        d      t        j                   d|j                   dt         d       | j#                  |j%                               S t'        d|j                   d	      )r   z8Unioning two intervals of different axes is not allowed.rG   rH   r   r   r   r   rj   rk   N)r   r>   rC   r   rl   r   rA   r   rB   rD   rE   rm   rQ   rp   r   r   r   unionrn   rr   r   s          r$   r   zInterval.unionS  s    eX&yyEJJ&'N  ~~

EKK0%)),II&&%%  y)!&!2!2Cc3yyC S$**!5sCTXX<NPSTTc! c#tzz&:CS$((ASTT " }-, [  >u>OOefoep  qP  Q zz%"4"4"677 1%//1B*MNNr&   c                    | j                   dk(  rO| j                  |z
  }| j                  |z   }|s|r{t        j                  d| j
                  j                          nN| j                  |z
  }| j                  |z   }|s|r,t        j                  d| j
                  j                          |rt        d|      }| j                  ||      S )NrG   z)Invalid padding top/bottom for an x axis z(Invalid padding right/left for a y axis r   rX   )	rC   rA   rB   r   r   rl   __name__r   rc   )r   leftrighttopbottom	safe_moderA   rB   s           r$   ry   zInterval.pady  s    99JJ%E((U"Cf?@W@W?XY JJ$E((V#Cu>t~~?V?V>WX 5MExxex--r&   c                     t        |t              r<| j                  dk(  r|d   n|d   }t        j                  d| j                   d       | j
                  |z   }| j                  |z   }| j                  ||      S )a5  
        Shift the interval by a user specified amount along the same axis that the interval is defined on.

        Args:
            shift_distance (:obj:`numeric`): The number of pixels used to shift the interval.

        Returns:
            :obj:`BaseCoordElement`: The shifted Interval object.
        rG   r   r   z=Input shift for multiple axes. Only use the distance for the  axisrX   r   r	   rC   r   r   rA   rB   rc   )r   shift_distancerA   rB   s       r$   shiftzInterval.shift  s     nh/%)YY#%5q!>!;L  MMOPTPYPY{Z_` 

^+hh'xxex--r&   c                     t        |t              r<| j                  dk(  r|d   n|d   }t        j                  d| j                   d       | j
                  |z  }| j                  |z  }| j                  ||      S )a6  
        Scale the layout element by a user specified amount the same axis that the interval is defined on.

        Args:
            scale_factor (:obj:`numeric`): The amount for downscaling or upscaling the element.

        Returns:
            :obj:`BaseCoordElement`: The scaled Interval object.
        rG   r   r   z;Input scale for multiple axes. Only use the factor for the r   rX   r   )r   scale_factorrA   rB   s       r$   scalezInterval.scale  sw     lH-.2ii3.><?LQROLMMMdii[X]^ 

\)hh%xxex--r&   c                     | j                  |      j                  \  }}}}|t        |      t        |      t        |      t        |      f   S r   )rg   rQ   intr   imager{   r|   r}   r~   s         r$   
crop_imagezInterval.crop_image  sK    !//6BBS#sSXC(#c(SX*==>>r&   c                 &    t        | j                   S )z
        Convert the Interval to a Rectangle element.

        Returns:
            :obj:`Rectangle`: The converted Rectangle object.
        rm   rQ   rK   s    r$   rn   zInterval.to_rectangle  s     $**++r&   c                 ,    t        | j                        S )z
        Convert the Interval to a Quadrilateral element.

        Returns:
            :obj:`Quadrilateral`: The converted Quadrilateral object.
        rp   rT   rK   s    r$   rq   zInterval.to_quadrilateral  s     T[[))r&   NNTr   r   r   r   T)r   
__module____qualname__r1   _name	_featuresrI   propertyrL   rN   rQ   rT   rY   r[   rg   r<   ro   rv   r   r   boolr   r   ry   r   r   r   rn   rq   rx   r&   r$   r>   r>   S   sJ   " EII
. ) ) ) )  " 	; 	; - - ( (94 O O* O O* ')% O O< %O/ %O %O %ON #O+ #OT #O #OJ.,...*?,*r&   r>   c                      e Zd ZdZdZg dZd Zed        Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zei dfd       Zeddedefd       Zeddedefd       ZddZddZddZd Zd Zd Zy)rm   a  
    This class describes the coordinate system of an axial rectangle box using two points as indicated below::

            (x_1, y_1) ----
            |             |
            |             |
            |             |
            ---- (x_2, y_2)

    Args:
        x_1 (:obj:`numeric`):
            x coordinate on the horizontal axis of the upper left corner of the rectangle.
        y_1 (:obj:`numeric`):
            y coordinate on the vertical axis of the upper left corner of the rectangle.
        x_2 (:obj:`numeric`):
            x coordinate on the horizontal axis of the lower right corner of the rectangle.
        y_2 (:obj:`numeric`):
            y coordinate on the vertical axis of the lower right corner of the rectangle.
    	rectangler{   r|   r}   r~   c                 <    || _         || _        || _        || _        y r   r   )r   r{   r|   r}   r~   s        r$   rI   zRectangle.__init__  s    r&   c                 4    | j                   | j                  z
  S )z
        Calculate the height of the rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        )r~   r|   rK   s    r$   rL   zRectangle.height       xx$((""r&   c                 4    | j                   | j                  z
  S )z
        Calculate the width of the rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        )r}   r{   rK   s    r$   rN   zRectangle.width  r   r&   c                 ^    | j                   | j                  | j                  | j                  fS )z
        Return the coordinates of the two points that define the rectangle.

        Returns:
            :obj:`Tuple(numeric)`: Output the numeric values of the coordinates in a Tuple of size four.
        r   rK   s    r$   rQ   zRectangle.coordinates  s#     $((DHHdhh77r&   c                 ,    t        | j                        S )z
        Return the coordinates of all four corners of the rectangle in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        rS   rK   s    r$   rT   zRectangle.points  rU   r&   c                 r    | j                   | j                  z   dz  | j                  | j                  z   dz  fS )z
        Calculate the center of the rectangle.

        Returns:
            :obj:`Tuple(numeric)`: Returns of coordinate of the center.
        rW   )r{   r}   r|   r~   rK   s    r$   rY   zRectangle.center  s3     488#s*TXX-@C,GGGr&   c                 4    | j                   | j                  z  S )z3
        Return the area of the rectangle.
        )rN   rL   rK   s    r$   r[   zRectangle.area*  s    
 zzDKK''r&   c                    t        |t              rt|j                  dk(  r|j                  d}}nd|j                  }}| j	                  | j
                  |z   | j                  |z   | j                  |z   | j                  |z         S t        |t              rY|j                  \  }}}}| j	                  | j
                  |z   | j                  |z   | j                  |z   | j                  |z         S t        |t              rIt        |j                  | j                  d      }|j	                  || j                  | j                         S t#        d|j                   d      NrG   r   Tis_invrj   rk   r   r>   rC   rA   rl   r{   r|   r}   r~   rm   rQ   rp   r   perspective_matrixrT   rL   rN   rr   r   r;   dxdy_transformed_pointss         r$   ro   zRectangle.condition_on1  s)    eX&zzS aBEKKB>>2txx"}dhhmTXX]  y) ,,LBAq>>2txx"}dhhmTXX]  }-!;(($++d" ??#5t{{DJJOO 1%//1B*MNNr&   c                    t        |t              rt|j                  dk(  r|j                  d}}nd|j                  }}| j	                  | j
                  |z
  | j                  |z
  | j                  |z
  | j                  |z
        S t        |t              rY|j                  \  }}}}| j	                  | j
                  |z
  | j                  |z
  | j                  |z
  | j                  |z
        S t        |t              rIt        |j                  | j                  d      }|j	                  || j                  | j                         S t#        d|j                   d      NrG   r   Fr   rj   rk   r   r   s         r$   rv   zRectangle.relative_toO  s'   eX&zzS aBEKKB>>2txx"}dhhmTXX]  y) ,,LBAq>>2txx"}dhhmTXX]  }-!;(($++e" ??#5t{{DJJOO 1%//1B*MNNr&   Fc                     |j                   d	i |}t        |t              r|sl|j                  dk(  r| j                  | j
                  }}n| j                  | j                  }}|j                  |cxk  xr |cxk  xr |j                  k  S c S |j                  dk(  r| j                  d   n| j                  d   }|j                  |cxk  xr |j                  k  S c S t        |t              rL|j                  d      }|j                  d      }| j                  ||      xr | j                  ||      S t        |t              ro|s8| j                  D 	cg c]  }	t!        |	|j                         }
}	t#        |
      S t%        j&                  | j                        }t!        ||j                        S t)        d|j*                   d      c c}	w )
NrG   r   r   rC   rH   rY   rj   rk   rx   )ry   r   r>   rC   r{   r}   r|   r~   rA   rB   rY   rm   to_intervalr   rp   rT   r   allr^   arrayrr   rl   r   r;   rz   rY   rA   rB   c
x_interval
y_intervalverticeis_vertice_ins              r$   r   zRectangle.is_inl  s    		(K(eX&::$!%4883E!%4883E{{e?s?eii????&+jjC&7DKKNT[[^{{a45994444y)***4J***4J::j:8 TZZ6 >H >  }- NR[[!BI&w=! ! =))$++.)&%,,?? 1%//1B*MNN!s   Gr;   r   c           	      z   t        |t              r|j                  |       S t        |t              r| j	                  t        | j                  |j                        t        | j                  |j                        t        | j                  |j                        t        | j                  |j                              S t        |t              rV|rt        d      t        j                  d|j                   dt         d       | j                  |j                               S t!        d|j                   d      )r   a  The intersection between a Rectangle and a Quadrilateral might generate Polygon shapes that are not supported in the current version of layoutparser. You can pass `strict=False` in the input that converts the Quadrilateral to Rectangle to avoid this Exception.r   r   r   rj   rk   )r   r>   r   rm   rl   r   r{   r|   r   r}   r~   rp   r   r   r   rn   rr   r   r;   r   s      r$   r   zRectangle.intersect  s    eX&??4((y)>>DHHeii(DHHeii(DHHeii(DHHeii(	  }-, [  >u>OOefoep  qP  Q ~~e&8&8&:;; 1%//1B*MNNr&   c           	      z   t        |t              r|j                  |       S t        |t              r| j	                  t        | j                  |j                        t        | j                  |j                        t        | j                  |j                        t        | j                  |j                              S t        |t              rV|rt        d      t        j                  d|j                   dt         d       | j                  |j!                               S t#        d|j                   d      )r   r   r   r   r   rj   rk   )r   r>   r   rm   rl   r   r{   r|   r   r}   r~   rp   r   r   r   r   rn   rr   r   s      r$   r   zRectangle.union  s    eX&??4((y)>>DHHeii(DHHeii(DHHeii(DHHeii(	  }-, [  >u>OOefoep  qP  Q zz%"4"4"677 1%//1B*MNNr&   c                     | j                   |z
  }| j                  |z
  }| j                  |z   }| j                  |z   }	|rt	        d|      }t	        d|      }| j                  ||||	      S )Nr   )r{   r|   r}   r~   r   rl   )
r   r   r   r   r   r   r{   r|   r}   r~   s
             r$   ry   zRectangle.pad  sf    hhohhnhhhha+Ca+C~~c3S11r&   c                     t        |t              s|}|}nt        |      dk(  sJ d       |\  }}| j                  |z   }| j                  |z   }| j
                  |z   }| j                  |z   }| j                  ||||      S )Nr]   Rshift_distance should have 2 elements, one for x dimension and one for y dimensionr   r	   lenr{   r|   r}   r~   rl   )r   r   shift_xshift_yr{   r|   r}   r~   s           r$   r   zRectangle.shift  s    .(3$G$G N#q(dcd(-GWhh hh hh hh ~~c3S11r&   c                     t        |t              s|}|}nt        |      dk(  sJ d       |\  }}| j                  |z  }| j                  |z  }| j
                  |z  }| j                  |z  }| j                  ||||      S )Nr]   Pscale_factor should have 2 elements, one for x dimension and one for y dimensionr   )r   r   scale_xscale_yr{   r|   r}   r~   s           r$   r   zRectangle.scale  s    ,1"G"G L!Q&bab&+GWhh hh hh hh ~~c3S11r&   c                     | j                   \  }}}}|t        |      t        |      t        |      t        |      f   S r   )rQ   r   r   s         r$   r   zRectangle.crop_image  s@    !--S#sSXC(#c(SX*==>>r&   c                     |dk(  r| j                   | j                  }}n| j                  | j                  }}t	        ||fd|i|S NrG   rC   )r{   r}   r|   r~   r>   )r   rC   r!   rA   rB   s        r$   r   zRectangle.to_interval   sB    3;4883E4883Es8888r&   c                 ,    t        | j                        S r   r   rK   s    r$   rq   zRectangle.to_quadrilateral  s    T[[))r&   Nr   r   r   r   )r   r   r   r1   r   r   rI   r   rL   rN   rQ   rT   rY   r[   r<   ro   rv   r   r   r   r   r   ry   r   r   r   r   rq   rx   r&   r$   rm   rm     sF   ( E,I # # # # 8 8 	; 	; H H ( ( O O: O O8 ')% $O $OL O/ O O O: O+ OT O O622"2"?9*r&   rm   c                       e Zd ZdZdZg dZ	 d!deej                  e	e	e	   f   fdZ
ed        Zed        Zed        Zed	        Zed
        Zed        Zed        Zed        Zd Zed        Zed        Zei dfd       Zed"dedefd       Zed"dedefd       Zd#dZd$dZd%dZd Z d Z!d Z"d Z#d Z$de%e&e'f   f fd Z( xZ)S )&rp   a  
    This class describes the coodinate system of a four-sided polygon. A quadrilateral is defined by
    the coordinates of its 4 corners in a clockwise order starting with the upper left corner (as shown below)::

        points[0] -...- points[1]
        |                      |
        .                      .
        .                      .
        .                      .
        |                      |
        points[3] -...- points[2]

    Args:
        points (:obj:`Numpy array` or `list`):
            A `np.ndarray` of shape 4x2  for four corner coordinates
            or a list of length 8 for in the format of
            `[p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y]`
            or a list of length 4 in the format of
            `[[p0_x, p0_y], [p1_x, p1_y], [p2_x, p2_y], [p3_x, p3_y]]`.
        height (:obj:`numeric`, `optional`, defaults to `None`):
            The height of the quadrilateral. This is to better support the perspective
            transformation from the OpenCV library.
        width (:obj:`numeric`, `optional`, defaults to `None`):
            The width of the quadrilateral. Similarly as height, this is to better support the perspective
            transformation from the OpenCV library.
    quadrilateral)rT   rL   rN   rT   c                    t        |t        j                        r(|j                  dk7  rt	        d|j                   d      t        |t
              rt        |      dk(  r&t        j                  |      j                  dd      }ngt        |      dk(  r)t        |d   t
              rt        j                  |      }n0t	        dt        |       d	      t	        d
t        |       d      || _
        || _        || _        y )N)   r]   zInvalid points shape: .   r   r]   r   z!Invalid number of points element z. Should be 8.zInvalid input type for points z-.Please make sure it is a list of np.ndarray.)r   r^   r_   r`   
ValueErrorlistr   r   reshapetype_points_width_height)r   rT   rL   rN   s       r$   rI   zQuadrilateral.__init__,  s     fbjj)||v% #9&,,q!IJJ%6{a&)11!Q7V!jD&A&) 7F}NS  0f ?? ? 
 r&   c                     | j                   | j                   S | j                  dddf   j                         | j                  dddf   j                         z
  S )z
        Return the user defined height, otherwise the height of its circumscribed rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        Nr   )r   rT   r   r   rK   s    r$   rL   zQuadrilateral.heightF  sO     <<#<<{{1a4 $$&QT):)>)>)@@@r&   c                     | j                   | j                   S | j                  dddf   j                         | j                  dddf   j                         z
  S )z
        Return the user defined width, otherwise the width of its circumscribed rectangle.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        Nr   )r   rT   r   r   rK   s    r$   rN   zQuadrilateral.widthS  sO     ;;";;{{1a4 $$&QT):)>)>)@@@r&   c                 ,    t        | j                        S )a  
        Return the coordinates of the upper left and lower right corners points that
        define the circumscribed rectangle.

        Returns
            :obj:`Tuple(numeric)`: Output the numeric values of the coordinates in a Tuple of size four.
        )r   rT   rK   s    r$   rQ   zQuadrilateral.coordinates`  s     )55r&   c                     | j                   S )z
        Return the coordinates of all four corners of the quadrilateral in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        )r   rK   s    r$   rT   zQuadrilateral.pointsl  s     ||r&   c                 h    t        | j                  j                  d      j                               S )z
        Calculate the center of the quadrilateral.

        Returns:
            :obj:`Tuple(numeric)`: Returns of coordinate of the center.
        r   r   )tuplerT   meantolistrK   s    r$   rY   zQuadrilateral.centerx  s*     T[[%%1%-44677r&   c                 ^    t        | j                  dddf   | j                  dddf         S )z7
        Return the area of the quadrilateral.
        Nr   r   )r   rT   rK   s    r$   r[   zQuadrilateral.area  s+    
 DKK1-t{{1a4/@AAr&   c                     dd| j                   | j                   d}dd| j                  | j                  d}| j                  ||      S )Nr   r   r   r]      )rN   rL   map_to_points_ordering)r   x_mapy_maps      r$   mapped_rectangle_pointsz%Quadrilateral.mapped_rectangle_points  sC     !

tzz:!<**5%88r&   c                 ~    t        | j                  j                  d      | j                  j                  d            S )Nfloat32)_getPerspectiveTransformrT   astyper  rK   s    r$   r   z Quadrilateral.perspective_matrix  s5    'KKy)((//	:
 	
r&   c                 D   | j                   j                  d      j                  d      }t        j                   t        j                  |j
                        |d d df          t        j                  |j
                        |d d df         g      j                  S )Nr   r   r   )rT   argsortr^   vstack	vectorizegetT)r   r  r  points_orderings       r$   r  z$Quadrilateral.map_to_points_ordering  s    ++--1-5==1=E yy'UYY'1(=>'UYY'1(=>

 !	r&   c                    t        |t              rI|j                  dk(  r| j                  |j                  dg      S | j                  d|j                  g      S t        |t
              r'| j                  |j                  |j                  g      S t        |t              rIt        |j                  | j                  d      }| j                  || j                  | j                        S t        d|j                   d      r   r   r>   rC   r   rA   rm   r{   r|   rp   r   r   rT   rl   rL   rN   rr   r   r;   r   s      r$   ro   zQuadrilateral.condition_on  s     eX&zzS zz5;;"233zz1ekk"233y)::uyy%))455}-!;(($++d" >>"4dkk4::NN 1%//1B*MNNr&   c                    t        |t              rK|j                  dk(  r| j                  |j                   dg      S | j                  d|j                   g      S t        |t
              r)| j                  |j                   |j                   g      S t        |t              rIt        |j                  | j                  d      }| j                  || j                  | j                        S t        d|j                   d      r   r  r  s      r$   rv   zQuadrilateral.relative_to  s     eX&zzS zzEKK<"344zz1u{{l"344y)::		zEII:677}-!;(($++e" >>"4dkk4::NN 1%//1B*MNNr&   Fc                     |j                   di |}t        |t              r|sx|j                  dk(  r| j                  d   | j                  d   }}n| j                  d   | j                  d   }}|j
                  |cxk  xr |cxk  xr |j                  k  S c S |j                  dk(  r| j                  d   n| j                  d   }|j
                  |cxk  xr |j                  k  S c S t        |t              rL|j                  d      }|j                  d      }| j                  ||      xr | j                  ||      S t        |t              ro|s8| j                  D 	cg c]  }	t        |	|j                         }
}	t        |
      S t        j                   | j                        }t        ||j                        S t#        d	|j$                   d
      c c}	w )NrG   r   r]   r   r   r   rH   r   rj   rk   rx   )ry   r   r>   rC   rQ   rA   rB   rY   rm   r   r   rp   rT   r   r   r^   r   rr   rl   r   s              r$   r   zQuadrilateral.is_in  s    		(K(eX&::$!%!1!1!!4d6F6Fq6I3E!%!1!1!!4d6F6Fq6I3E{{e?s?eii????&+jjC&7DKKNT[[^{{a45994444y)***4J***4J::j:8 TZZ6 >H >  }- NR[[!BI&w=! ! =))$++.)&%,,?? 1%//1B*MNN!s   *G"r;   r   c                    |rt        d      t        |t              st        |t              r<t	        j
                  dt         d       |j                  | j                               S t        |t              rJt	        j
                  dt         d       | j                         j                  |j                               S t        d|j                   d      r   a  The intersection between a Quadrilateral and other objects might generate Polygon shapes that are not supported in the current version of layoutparser. You can pass `strict=False` in the input that converts the Quadrilateral to Rectangle to avoid this Exception.zKWith `strict=False`, the current Quadrilateral object will be converted to r   zKWith `strict=False`, both input Quadrilateral objects will be converted to rj   rk   )r   r   r>   rm   r   r   r   rn   rp   rr   rl   r   s      r$   r   zQuadrilateral.intersect  s     ( Y  %*j	.Jabkal  mL  M t'8'8':;;E=1abkal  mL  M ((*44U5G5G5IJJ"5eoo5Fj QRRr&   c                    |rt        d      t        |t              st        |t              r<t	        j
                  dt         d       |j                  | j                               S t        |t              rJt	        j
                  dt         d       | j                         j                  |j                               S t        d|j                   d      r  )r   r   r>   rm   r   r   r   rn   rp   rr   rl   r   s      r$   r   zQuadrilateral.union  s     ( Y  %*j	.Jabkal  mL  M {{4#4#4#677E=1abkal  mL  M ((*001C1C1EFF"5eoo5Fj QRRr&   c                     | | ||d}| | ||d}| j                  ||      }| j                  |z   }	|rt        j                  |	d      }	| j	                  |	      S )Nr   r   rT   )r  rT   r^   maximumrc   )
r   r   r   r   r   r   r  r  padding_matrT   s
             r$   ry   zQuadrilateral.pad'  sj    Ete%8DcTf811%?{*ZZ*Fxxvx&&r&   c                     t        |t              s||g}nt        |      dk(  sJ d       |}| j                  t	        j
                  |      z   }| j                  |      S )Nr]   r   r  r   r	   r   rT   r^   r   rc   )r   r   	shift_matrT   s       r$   r   zQuadrilateral.shift4  sd    .(3'8I N#q(dcd(&Irxx	22xxvx&&r&   c                     t        |t              s||g}nt        |      dk(  sJ d       |}| j                  t	        j
                  |      z  }| j                  |      S )Nr]   r   r  r  )r   r   	scale_matrT   s       r$   r   zQuadrilateral.scaleB  sd    ,1%|4I L!Q&bab&$Irxx	22xxvx&&r&   c                     t        || j                  t        | j                        t        | j                        f      S )z
        Crop the input image using the points of the quadrilateral instance.

        Args:
            image (:obj:`Numpy array`): The array of the input image.

        Returns:
            :obj:`Numpy array`: The array of the cropped image.
        )_warpPerspectiver   r   rN   rL   r   r   s     r$   r   zQuadrilateral.crop_imageP  s4      4**S_c$++>N,O
 	
r&   c                 ^    | j                   \  }}}}|dk(  r||}}n||}}t        ||fd|i|S r   )rQ   r>   )	r   rC   r!   r{   r|   r}   r~   rA   rB   s	            r$   r   zQuadrilateral.to_interval_  sF    !--S#s3;c3Ec3Es8888r&   c                 &    t        | j                   S r   r   rK   s    r$   rn   zQuadrilateral.to_rectanglei  s    $**++r&   c                     |j                   | j                   uryt        j                  | j                  |j                        j	                         S )NF)rl   r^   iscloserT   r   r   r;   s     r$   __eq__zQuadrilateral.__eq__l  s7    ??$..0zz$++u||488::r&   c                     g d}dj                  |D cg c]  }| dt        | |        c}      }| j                  j                   d| dS c c}w )N)rT   rN   rL   z, =())joinr4   rl   r   )r   keyskeyinfo_strs       r$   __repr__zQuadrilateral.__repr__q  sW    ,99tLQwtS'9&:;LM..))*!H:Q77 Ms   Areturnc                 n    t         |          }|d   j                  d      j                         |d<   |S )a  
        Generate a dictionary representation of the current object::

            {
                "block_type": "quadrilateral",
                "points": [
                    p[0,0], p[0,1],
                    p[1,0], p[1,1],
                    p[2,0], p[2,1],
                    p[3,0], p[3,1]
                ],
                "height": value,
                "width": value
            }
        rT   )superto_dictr   r   )r   datarl   s     r$   r7  zQuadrilateral.to_dictv  s7    " w h//3::<Xr&   r   r   r   r   r   )*r   r   r   r1   r   r   r   r^   r_   r   rI   r   rL   rN   rQ   rT   rY   r[   r  r   r  r<   ro   rv   r   r   r   r   r   ry   r   r   r   r   rn   r)  r2  r   strr   r7  __classcell__)rl   s   @r$   rp   rp     s   6 E-I OSBJJd4j894 
A 
A 
A 
A 	6 	6 	 	 8 8 B B 9 9 
 

 O O. O O. ')% $O $OL S/ S S S* S+ ST S S('''
9,;
8
c3h  r&   rp   c                   l   e Zd ZdZdZg dZ	 ddZed        Zed        Z	ed        Z
ed	        Zed
        Zed        Zed        Zi dfdZed dedefd       Zed dedefd       Zed        Zed!d       Zed        Zd Zd"dee   fdZd Zd Zdeeef   fdZ e!deeef   dd fd       Z"y)#r:   a  
    This class constructs content-related information of a layout element in addition to its coordinate definitions
    (i.e. Interval, Rectangle or Quadrilateral).

    Args:
        block (:obj:`BaseCoordElement`):
            The shape-specific coordinate systems that the text block belongs to.
        text (:obj:`str`, `optional`, defaults to None):
            The ocr'ed text results within the boundaries of the text block.
        id (:obj:`int`, `optional`, defaults to `None`):
            The id of the text block.
        type (:obj:`int`, `optional`, defaults to `None`):
            The type of the text block.
        parent (:obj:`int`, `optional`, defaults to `None`):
            The id of the parent object.
        next (:obj:`int`, `optional`, defaults to `None`):
            The id of the next block.
        score (:obj:`numeric`, defaults to `None`):
            The prediction confidence of the block
    	textblock)textidr   r7   nextscoreNc                     t        |t              sJ || _        || _        || _        || _        || _        || _        || _        y r   )	r   r   r   r=  r>  r   r7   r?  r@  )r   r   r=  r>  r   r7   r?  r@  s           r$   rI   zTextBlock.__init__  sF     %!1222
			
r&   c                 .    | j                   j                  S )z
        Return the height of the shape-specific block.

        Returns:
            :obj:`numeric`: Output the numeric value of the height.
        )r   rL   rK   s    r$   rL   zTextBlock.height  s     zz   r&   c                 .    | j                   j                  S )z
        Return the width of the shape-specific block.

        Returns:
            :obj:`numeric`: Output the numeric value of the width.
        )r   rN   rK   s    r$   rN   zTextBlock.width  s     zzr&   c                 .    | j                   j                  S )z
        Return the coordinates of the two corner points that define the shape-specific block.

        Returns:
            :obj:`Tuple(numeric)`: Output the numeric values of the coordinates in a Tuple of size four.
        )r   rQ   rK   s    r$   rQ   zTextBlock.coordinates  s     zz%%%r&   c                 .    | j                   j                  S )z
        Return the coordinates of all four corners of the shape-specific block in a clockwise fashion
        starting from the upper left.

        Returns:
            :obj:`Numpy array`: A Numpy array of shape 4x2 containing the coordinates.
        )r   rT   rK   s    r$   rT   zTextBlock.points  s     zz   r&   c                 .    | j                   j                  S )z6
        Return the area of associated block.
        )r   r[   rK   s    r$   r[   zTextBlock.area  s    
 zzr&   c                 8    | j                   j                  |      S r   )r   ro   r(  s     r$   ro   zTextBlock.condition_on  s    zz&&u--r&   c                 8    | j                   j                  |      S r   )r   rv   r(  s     r$   rv   zTextBlock.relative_to  s    zz%%e,,r&   Fc                 <    | j                   j                  |||      S r   )r   r   )r   r;   rz   rY   s       r$   r   zTextBlock.is_in  s    zz{F;;r&   r;   r   c                 <    | j                   j                  ||      S N)r   )r   r   r   s      r$   r   zTextBlock.union  s    zzf55r&   c                 <    | j                   j                  ||      S rK  )r   r   r   s      r$   r   zTextBlock.intersect  s    zz##E&#99r&   c                 8    | j                   j                  |      S r   )r   r   )r   r   s     r$   r   zTextBlock.shift  s    zz//r&   c                 @    | j                   j                  |||||      S r   )r   ry   )r   r   r   r   r   r   s         r$   ry   zTextBlock.pad  s    zz~~dE3	BBr&   c                 8    | j                   j                  |      S r   )r   r   )r   r   s     r$   r   zTextBlock.scale  s    zz--r&   c                 8    | j                   j                  |      S r   )r   r   r#  s     r$   r   zTextBlock.crop_image  s    zz$$U++r&   rC   c                     t        | j                  t              r| S |st        dd d      | j	                   | j                  j
                  dd|i|      S )Nz#Please provide valid `axis` values rG   z as the inputrC   r   rx   )r   r   r>   r   rc   r   )r   rC   r!   s      r$   r   zTextBlock.to_interval  s^    djj(+K 9#]S  88"8$**"8"8"Md"Mf"M8NNr&   c                     t        | j                  t              r| S | j                  | j                  j	                               S NrR  )r   r   rm   rc   rn   rK   s    r$   rn   zTextBlock.to_rectangle  s3    djj),K88$**"9"9";8<<r&   c                     t        | j                  t              r| S | j                  | j                  j	                               S rT  )r   r   rp   rc   rq   rK   s    r$   rq   zTextBlock.to_quadrilateral"  s3    djj-0K88$**"="="?8@@r&   r3  c                     | j                   j                         }| j                  D ]   }t        | |      }|t        | |      ||<   " |S )a  
        Generate a dictionary representation of the current textblock of the format::

            {
                "block_type": <name of self.block>,
                <attributes of self.block combined with
                    non-empty self._features>
            }
        )r   r7  r   r4   )r   	base_dictfvals       r$   r7  zTextBlock.to_dict(  sR     JJ&&(	 	0A$"C&tQ/	!	0 r&   r8  c                     |d   t         v sJ d|d           t         |d      j                  |      } | |fi | j                  D ci c]  }||j                  |d       c}S c c}w )a/  Initialize the textblock based on the dictionary representation.
        It generate the block based on the `block_type` and `block_attr`,
        and loads the textblock specific features from the dict.

        Args:
            data (:obj:`dict`): The dictionary representation of the object
        
block_typezInvalid block_type N)BASECOORD_ELEMENT_NAMEMAP	from_dictr   r  )r5   r8  r   rX  s       r$   r]  zTextBlock.from_dict9  s}     ";;	6 l!3 45	6; *$|*<=GGM5J3==IaQD 11IJJIs   A&)NNNNNNr   r   r   )#r   r   r   r1   r   r   rI   r   rL   rN   rQ   rT   r[   r+   ro   rv   r   r   r   r   r   r   ry   r   r   r   r9  r   rn   rq   r   r   r7  classmethodr]  rx   r&   r$   r:   r:     s   * EAI SW ! !     & & 	! 	!   . . - - (*% < 6+ 6T 6 6 :/ : : : 0 0 C C . .,O O=Ac3h " KT#s(^ K K Kr&   r:   r   )2typingr   r   r   r   r   r   collections.abcr	   r
   inspectr   r   r   r(   numpyr^   pandaspdPILr   cv2r   r  r   r"  baser   r   utilsr   r   r   r   r   errorsr   r   r+   r0   r<   r>   rm   rp   ALL_BASECOORD_ELEMENTSr   r\  	enumerateBASECOORD_ELEMENT_INDEXMAPr:   )eleidxs   00r$   <module>ro     s:   A @ @ $  *      C 3 5  >	t * {* {* {*| v*  v* v*r	 |$ | |~ #I}= 7MNSYY^N #,-C#DsCCIIsN 
 /0sK! sK 1sK Os   -DD