Ë
    £èh ã                  óR  — d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
mZ ddlZddlZddlZddlmZmZ ddlmZmZmZmZmZmZ ddlmZmZmZmZmZmZm Z  ddl!m"Z"m#Z#m$Z$ dd	l%m&Z&m'Z'm(Z( erdd
l)m*Z*m+Z+m,Z, ddl-m.Z. ddl/m0Z0 dZ1 G d„ d«      Z2dGd„Z3dHd„Z4dId„Z5dJd„Z6dZ7dKdLd„Z8dJd„Z9dMdNd„Z:	 	 dO	 	 	 	 	 dPd„Z;dJd„Z<dQdRd„Z=dSd„Z>	 	 	 	 	 	 	 	 dTd„Z?dUd„Z@ej‚                  dej4                  dej8                  d ej6                  d!ej„                  d"ej†                  d#iZDd$ZEd%ZFdVd&„ZG G d'„ d(e
«      ZH G d)„ d*«      ZI G d+„ d,eJ«      ZK G d-„ d.«      ZL G d/„ d0«      ZM G d1„ d2ejœ                  «      ZO G d3„ d4«      ZP ej¢                  d5«      ZR ej¢                  d6«      ZSej4                  ej8                  ej6                  ej„                  ej†                  d7œZT G d8„ d9«      ZUdWd:„ZVdXd;„ZWdYdZd<„ZXdYd[d=„ZYd\d]d>„ZZd^d?„Z[d@a\d_dA„Z]d`dB„Z^	 	 da	 	 	 	 	 	 	 	 	 dbdC„Z_e fdcdD„Z` eadE«      ZbdddF„Zcy)ezL
Tools in this module should be as independent of DXF entities as possible!
é    )Úannotations)ÚIterableÚIteratorÚTYPE_CHECKINGÚUnionÚOptionalÚCallableÚ
NamedTupleÚAnyN)Ú	validatorÚconst)ÚTextEntityAlignmentÚ
TextHAlignÚMTextParagraphAlignmentÚMTextLineAlignmentÚMTextStrokeÚMAP_MTEXT_ALIGN_TO_FLAGS)ÚLEFTÚCENTERÚRIGHTÚBASELINEÚMIDDLEÚTOPÚMAX_STR_LEN)ÚVec3ÚVec2ÚUVec)Úrgb2intÚRGBÚint2rgb)ÚTextÚMTextÚ	DXFEntity)ÚTags©Úfontsé   c                  ó  — e Zd ZdZdd„Zdd„Zedd„«       Zedd„«       Zdd„Z		 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd	„Z
	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 dd
„Z	 	 	 	 	 	 	 	 dd„Ze eddd«      ddddf	 	 	 	 	 	 	 	 	 	 	 	 	 dd„«       Zy)ÚTextLinea  Helper class which represents a single line text entity
    (e.g. :class:`~ezdxf.entities.Text`).

    Args:
        text: content string
        font: ezdxf font definition like :class:`~ezdxf.fonts.fonts.MonospaceFont`
            or :class:`~ezdxf.fonts.fonts.TrueTypeFont`

    c                óZ   — || _         |j                  |«      | _        d| _        d| _        y )Nç      ð?)Ú_fontÚ
text_widthÚ_text_widthÚ
_stretch_xÚ
_stretch_y)ÚselfÚtextÚfonts      ú0lib/python3.12/site-packages/ezdxf/tools/text.pyÚ__init__zTextLine.__init__?   s(   € ØˆŒ
Ø"&§/¡/°$Ó"7ˆÔØ!$ˆŒØ!$ˆ�ó    c                ó  — t        |t        «      sJ ‚d}d}|t        j                  t        j                  fv rB||z
  j                  }| j
                  dkD  r$|| j
                  z  }|t        j                  k(  r|}|| _        || _        y)zÓSet stretch factors for FIT and ALIGNED alignments to fit the
        text between `p1` and `p2`, only the distance between these points is
        important. Other given `alignment` values are ignore.

        r+   g•Ö&è.>N)Ú
isinstancer   ÚFITÚALIGNEDÚ	magnituder.   r/   r0   )r1   Ú	alignmentÚp1Úp2ÚsxÚsyÚdefined_lengths          r4   ÚstretchzTextLine.stretchE   s‰   € ô ˜)Ô%8Ô9Ð9Ð9ØˆØˆØÔ,×0Ñ0Ô2E×2MÑ2MÐNÑNØ%'¨"¡W×$7Ñ$7ˆNØ×Ñ $Ò&Ø# d×&6Ñ&6Ñ6�ØÔ 3× ;Ñ ;Ò;Ø�BØˆŒØˆ�r6   c                ó4   — | j                   | j                  z  S )z)Returns the final (stretched) text width.)r.   r/   ©r1   s    r4   ÚwidthzTextLine.widthW   s   € ð ×Ñ $§/¡/Ñ1Ð1r6   c                ó\   — | j                   j                  j                  | j                  z  S )z*Returns the final (stretched) text height.)r,   ÚmeasurementsÚtotal_heightr0   rD   s    r4   ÚheightzTextLine.height\   s#   € ð �z‰z×&Ñ&×3Ñ3°d·o±oÑEÐEr6   c                ó`   — | j                   j                  j                  | j                  «      S )z%Returns the scaled font measurements.)r,   rG   Úscaler0   rD   s    r4   Úfont_measurementszTextLine.font_measurementsa   s!   € à�z‰z×&Ñ&×,Ñ,¨T¯_©_Ó=Ð=r6   r   ©é   rN   c                óæ   — | j                  «       }t        d|j                  «      t        | j                  |j                  «      g}| j	                  |||«      }t
        j                  |||||«      S )az  Returns the left and the right baseline vertex of the text line.

        Args:
            insert: insertion location
            halign: horizontal alignment left=0, center=1, right=2
            valign: vertical alignment baseline=0, bottom=1, middle=2, top=3
            angle: text rotation in radians
            scale: scale in x- and y-axis as 2-tuple of float

        r   )rL   r   ÚbaselinerE   Ú_shift_vectorr)   Útransform_2d)	r1   ÚinsertÚhalignÚvalignÚanglerK   ÚfmÚverticesÚshifts	            r4   Úbaseline_verticeszTextLine.baseline_verticese   sj   € ð$ ×#Ñ#Ó%ˆä��B—K‘KÓ Ü�—‘˜RŸ[™[Ó)ð
ˆð ×"Ñ" 6¨6°2Ó6ˆô ×$Ñ$ X¨v°u¸eÀUÓKÐKr6   c                óP  — | j                  «       }t        d|j                  «      t        | j                  |j                  «      t        | j                  |j                  «      t        d|j                  «      g}| j                  |||«      }	t        j                  |||	|||«      S )añ  Returns the corner vertices of the text line in the order
        bottom left, bottom right, top right, top left.

        Args:
            insert: insertion location
            halign: horizontal alignment left=0, center=1, right=2
            valign: vertical alignment baseline=0, bottom=1, middle=2, top=3
            angle: text rotation in radians
            scale: scale in x- and y-axis as 2-tuple of float
            oblique: shear angle (slanting) in x-direction in radians

        r   )rL   r   ÚbottomrE   Úcap_toprQ   r)   rR   )
r1   rS   rT   rU   rV   rK   ÚobliquerW   rX   rY   s
             r4   Úcorner_verticeszTextLine.corner_vertices�   sŠ   € ð* ×#Ñ#Ó%ˆä��B—I‘IÓÜ�—‘˜RŸY™YÓ'Ü�—‘˜RŸZ™ZÓ(Ü��B—J‘JÓð	
ˆð ×"Ñ" 6¨6°2Ó6ˆÜ×$Ñ$ X¨v°u¸eÀUÈGÓTÐTr6   c                óF   — t        | j                  |«      t        ||«      fS ©N)Ú_shift_xrE   Ú_shift_y)r1   rT   rU   rW   s       r4   rQ   zTextLine._shift_vector    s!   € ô ˜Ÿ
™
 FÓ+¬X°b¸&Ó-AÐAÐAr6   )r   r   c                ó@  ‡‡‡	‡
‡— t        j                  | «      }|r t        j                  |«      Šˆfd„|D «       }t        |«      Š
‰
rˆ
fd„|D «       }|\  ŠŠ	‰dk7  s‰	dk7  rˆˆ	fd„|D «       }‰rˆfd„|D «       }t	        |«      }|D �cg c]  }||z   ‘Œ	 c}S c c}w )aÁ  Transform any vertices from the text line located at the base
        location at (0, 0) and alignment LEFT.

        Args:
            vertices: iterable of vertices
            insert: insertion location
            shift: (shift-x, shift-y) as 2-tuple of float
            rotation: text rotation in radians
            scale: (scale-x, scale-y)  as 2-tuple of float
            oblique: shear angle (slanting) in x-direction in radians

        c              3  ó~   •K  — | ]4  }t        |j                  |j                  ‰z  z   |j                  «      –— Œ6 y ­wra   ©r   ÚxÚy)Ú.0ÚvÚslant_xs     €r4   Ú	<genexpr>z(TextLine.transform_2d.<locals>.<genexpr>Ì   s.   øè ø€ ÐKÁ¸Aœ˜aŸc™c A§C¡C¨'¡MÑ1°1·3±3×7Áùs   ƒ:=c              3  ó(   •K  — | ]	  }|‰z   –— Œ y ­wra   © )ri   rj   Úshift_vectors     €r4   rl   z(TextLine.transform_2d.<locals>.<genexpr>Ñ   s   øè ø€ Ð=±9¨a˜˜\Õ)±9ùs   ƒrN   c              3  ój   •K  — | ]*  }t        |j                  ‰z  |j                  ‰z  «      –— Œ, y ­wra   rf   )ri   rj   Úscale_xÚscale_ys     €€r4   rl   z(TextLine.transform_2d.<locals>.<genexpr>Ö   s)   øè ø€ ÐOÁYÀœ˜aŸc™c G™m¨Q¯S©S°7©]×;ÁYùs   ƒ03c              3  ó@   •K  — | ]  }|j                  ‰«      –— Œ y ­wra   )Úrotate)ri   rj   Úrotations     €r4   rl   z(TextLine.transform_2d.<locals>.<genexpr>Ú   s   øè ø€ Ð?±Y°˜Ÿ™ (×+±Yùs   ƒ)r   ÚgenerateÚmathÚtanr   )rX   rS   rY   ru   rK   r^   Ú	vertices_rj   rq   rr   ro   rk   s      `    @@@@r4   rR   zTextLine.transform_2d¥   s¢   ü€ ôD %)§M¡M°(Ó$;ˆ	ñ Ü—h‘h˜wÓ'ˆGÛKÁÓKˆIô ˜E“{ˆÙÛ=±9Ó=ˆIð !Ñˆ�Ø�aŠ<˜7 aš<ÜOÁYÓOˆIñ Û?±YÓ?ˆIô �f“ˆÙ$-Ó.¡I˜q�˜“
 IÑ.Ð.ùÒ.s   ÂBN)r2   Ústrr3   úfonts.AbstractFont)r<   r   r=   r   r>   r   ÚreturnÚNone©r|   Úfloat)r|   úfonts.FontMeasurements)r   r   r   rM   )rS   r   rT   ÚintrU   r�   rV   r   rK   útuple[float, float]r|   ú
list[Vec3])r   r   r   rM   r   )rS   r   rT   r�   rU   r�   rV   r   rK   r‚   r^   r   r|   rƒ   )rT   r�   rU   r�   rW   r€   r|   r‚   )rX   zIterable[UVec]rS   r   rY   r‚   ru   r   rK   r‚   r^   r   r|   rƒ   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r5   rB   ÚpropertyrE   rI   rL   rZ   r_   rQ   Ústaticmethodr   rR   rn   r6   r4   r)   r)   4   s�  „ ñó%óð$ ò2ó ð2ð òFó ðFó>ð ØØØ%+ðLàðLð ðLð ð	Lð
 ðLð #ðLð 
óLð> ØØØ%+ØðUàðUð ðUð ð	Uð
 ðUð #ðUð ðUð 
óUð>BØðBØ#&ðBØ,BðBà	óBð
 ñ ˜A˜q !“}Ø%+ØØ%+Øð8/Ø ð8/àð8/ð #ð8/ð ð	8/ð
 #ð8/ð ð8/ð 
ò8/ó ñ8/r6   r)   c                ó:   — |t         k(  r|  dz  S |t        k(  r|  S y)Ng       @ç        )r   r   )Útotal_widthrT   s     r4   rb   rb   á   s)   € Ø”ÒØˆ|˜cÑ!Ð!Ø”‚Øˆ|ÐØr6   c                ó
  — |t         k(  r| j                  S |t        k(  r| j                   | j                  dz  z   S |t
        k(  r| j                   | j                  dz  z   S |t        k(  r| j                   S | j                   S )Né   )	r   rP   r   r]   Ú
cap_heightÚX_MIDDLErH   r   r\   )rW   rU   s     r4   rc   rc   é   sw   € Ø”ÒØ�{‰{ÐØ”ÒØ—
‘
ˆ{˜RŸ]™]¨QÑ.Ñ.Ð.Ø”ÒØ—
‘
ˆ{˜RŸ_™_¨qÑ0Ñ0Ð0Ø”‚}Ø—
‘
ˆ{ÐØ�I‰Iˆ:Ðr6   c                óº  — | j                  «       }|dv r�| j                  j                  }| j                  j                  }|t        j
                  t        j                  fv rt        }t        }||fS |t        j                  k(  rt        }t        }||fS |dk(  r4t        j                  | j                  j                  t        t        f«      S t!        d|› �«      ‚)z×Return unified horizontal and vertical alignment.

    horizontal alignment: left=0, center=1, right=2

    vertical alignment: baseline=0, bottom=1, middle=2, top=3

    Returns:
        tuple(halign, valign)

    )ÚTEXTÚATTRIBÚATTDEFÚMTEXTzinvalid DXF )ÚdxftypeÚdxfrT   rU   r   r:   r9   r   r   r   r�   r   ÚgetÚattachment_pointr   r   Ú	TypeError)Úentityr–   rT   rU   s       r4   Úunified_alignmentrœ   õ   sÆ   € ð �n‰nÓ€GØÐ.Ñ.Ø—‘×"Ñ"ˆØ—‘×"Ñ"ˆØ”j×(Ñ(¬*¯.©.Ð9Ñ9ô ˆFÜˆFð �vˆ~Ðð ”z×(Ñ(Ò(ÜˆFÜˆFØ�vˆ~ÐØ�'ÒÜ'×+Ñ+¨F¯J©J×,GÑ,GÌ$ÔPSÈÓUÐUÜ
�l 7 )Ð,Ó
-Ð-r6   c                óâ  — d}t        t        j                  t        | «      «      «      }|j                  r¹|j                  «       }|dk(  r�|j                  d«      dk(  rm|j                  d«      j                  «       }t        j                  j                  |«      }|r|j                  d«       ||z  }ŒŒ|dv r|j                  d«       Œ¢|j                  d«       ||z  }|j                  rŒ¹|S )z�Returns the plain text for :class:`~ezdxf.entities.Text`,
    :class:`~ezdxf.entities.Attrib` and :class:`~ezdxf.entities.Attdef` content.
    Ú Ú%rN   rŽ   é   Úkou)ÚTextScannerr   Úfix_one_line_textÚcaret_decodeÚhas_dataÚpeekÚlowerr   ÚSPECIAL_CHAR_ENCODINGr˜   Úconsume)r2   ÚresultÚscannerÚcharÚcodeÚletters         r4   Ú
plain_textr¯     sÕ   € ð €FÜœ)×5Ñ5´lÀ4Ó6HÓIÓJ€GØ
×
Ò
Ø�|‰|‹~ˆØ�3Š;Ø�|‰|˜A‹ #Ò%Ø—|‘| A“×,Ñ,Ó.�Ü×4Ñ4×8Ñ8¸Ó>�ÙØ—O‘O AÔ&Ø˜fÑ$�FØØ˜5‘=ð —O‘O AÔ&ØØ�‰˜Ôà�$‰ˆð# ×
Ó
ð$ €Mr6   Ú	PNLlOoKkXc                óþ  — g }t        t        t        | «      «      «      }|�rv|j                  «       }|dk(  r®	 |j                  «       }|dv r|j                  |«       �n5|t        v r0|dk(  r|j                  d«       �n|dk(  �r|j                  d«       ný|dk(  }|}|j                  «       }	 |dk7  r.|j                  «       }|r|dk7  r|j                  |«       |dk7  rŒ.|}n¯|d	v rnª|d
k(  r”|r€|d   d
k(  rx|j                  «        |r‰|j                  «       }t        j                  j                  |j                  «       «      }	|	r|j                  |	«       n8|j                  d
d
|f«       n#|j                  |«       n|j                  |«       |r�Œvdj                  |«      }
|r|
j                  d«      S |
S # t        $ r Y Œ1w xY w# t        $ r% |j                  d«       |j                  |«       Y Œfw xY w)a­  Returns the plain MTEXT content as a single string or  a list of
    strings if `split` is ``True``. Replaces ``\P`` by ``\n`` and removes
    other controls chars and inline codes.

    This function is more than 4x faster than :func:`plain_mtext`, but does not
    remove single letter inline commands with arguments without a terminating
    semicolon like this ``"\C1red text"``.

    .. note::

        Well behaved CAD applications and libraries always create inline codes
        for commands with arguments with a terminating semicolon like this
        ``"\C1;red text"``!

    Args:
        text: MTEXT content string
        split: split content at line endings ``\P``

    Ú\ú\{}ÚPÚ
ÚNÚ ÚSÚ;z{}rŸ   éÿÿÿÿrž   )ÚlistÚreversedr¤   ÚpopÚ
IndexErrorÚappendÚONE_CHAR_COMMANDSÚcopyr   r¨   r˜   r§   ÚextendÚjoinÚsplit)r2   rÄ   ÚcharsÚ	raw_charsr¬   ÚstackingÚ
first_charÚsearch_charsr­   r®   rª   s              r4   Úfast_plain_mtextrÊ   ¢  sÚ  € ð( €Eä”Xœl¨4Ó0Ó1Ó2€Iâ
Ø�}‰}‹ˆØ�4Š<ðØ —}‘}“�ð �v‰~Ø—‘˜TÖ"ØÔ*Ñ*Ø˜3’;Ø—L‘L Ö&Ø˜S“[ð —L‘L Õ%ð   3™;�Ø!�
Ø(Ÿ~™~Ó/�ð
-Ø #š+Ø+×/Ñ/Ó1˜Ù#¨°ªà!ŸL™L¨Ô.ð	  #›+ð
 !-‘Ið
 �T‰\ØØ�SŠ[Ù˜Y r™]¨cÒ1Ø—‘”ÙØ$Ÿ=™=›?�DÜ"×8Ñ8×<Ñ<¸T¿Z¹Z»\ÓJ�FÙØŸ™ VÕ,àŸ™ c¨3°Ð%5Õ6à—‘˜TÕ"à�L‰L˜Ôóa ðd �W‰W�U‹^€FÙ!&ˆ6�<‰<˜ÓÐ2¨FÐ2øô] ò Ùðûô0 "ò -à—L‘L Ô&Ø—L‘L Ö,ð-ús)   ¹F? Â02G Ã#G Æ?	GÇ
GÇ+G<Ç;G<c                ó8   — dd„}t        j                  d|| «      S )zæDXF stores some special characters using caret notation. This function
    decodes this notation to normalize the representation of special characters
    in the string.

    see: https://en.wikipedia.org/wiki/Caret_notation

    c                óX   — t        | j                  d«      «      }t        |dz
  dz  «      S )NrN   é@   é~   )ÚordÚgroupÚchr)ÚmatchÚcs     r4   Úreplace_matchz#caret_decode.<locals>.replace_matchù  s'   € Ü�—‘˜A“ÓˆÜ�A˜‘F˜c‘>Ó"Ð"r6   z\^(.))rÒ   zre.Matchr|   rz   )ÚreÚsub)r2   rÔ   s     r4   r¤   r¤   ð  s   € ó#ô �6‰6�(˜M¨4Ó0Ð0r6   c                óÌ   — g }d}	 | |||z    }t        |«      rJt        |«      |k  r|j                  |«       |S ||z  }|d   dk(  r
|dd }|dz  }|j                  |«       n|S Œ`)z9Split the MTEXT content string into chunks of max `size`.r   rº   Ú^NrN   )Úlenr¿   )ÚsÚsizeÚchunksÚposÚchunks        r4   Úsplit_mtext_stringrß      s‚   € à€FØ
€CØ
Ø�#˜˜d™
Ð#ˆÜˆuŒ:Ü�5‹z˜DÒ Ø—‘˜eÔ$Ø�Ø�4‰KˆCà�R‰y˜CÒØ˜c˜r˜
�Ø�q‘�Ø�M‰M˜%Õ àˆMð r6   c           	     ób  — g }g }t        t        «      ^}}}}}	}
}}}d|z  }t        | «      D ]Ê  }|j                  }||k(  r|j	                  |j
                  «       Œ0||k(  s||	k(  r|j	                  d«       ŒL||k(  s||k(  r1|j	                  dj                  |«      «       |j                  «        Œ‡||
k(  r|j	                  |«       Œž||k(  sŒ¤|j
                  \  }}}|j	                  ||z   |z   «       ŒÌ |r |j	                  dj                  |«      «       |r|S dj                  |«      S )aÂ  Returns the plain MTEXT content as a single string or a list of
    strings if `split` is ``True``. Replaces ``\P`` by ``\n`` and removes
    other controls chars and inline codes.

    This function is much slower than :func:`fast_plain_mtext`, but removes all
    inline codes.

    Args:
        text: MTEXT content string
        split: split content at line endings ``\P``
        tabsize: count of replacement spaces for tabulators ``^I``

    r·   rž   rµ   )ÚiterÚ	TokenTypeÚMTextParserÚtyper¿   ÚdatarÃ   Úclear)r2   rÄ   ÚtabsizeÚcontentÚ	paragraphÚ_ÚwordÚstackÚspaceÚnbspÚ	tabulatorÚnew_paragraphÚ
new_columnÚtab_replacementÚtokenÚtÚuprÚlwrÚdividers                      r4   Úplain_mtextrø     s/  € ð$ €GØ€Iô 	ŒY‹ð
Ø	ØØØØØØØØ	
à˜G‘m€Oô ˜TÖ"ˆØ�J‰JˆØ�Š9Ø×Ñ˜UŸZ™ZÕ(Ø�%ŠZ˜1 š9Ø×Ñ˜SÕ!Ø�-Ò 1¨
¢?Ø�N‰N˜2Ÿ7™7 9Ó-Ô.Ø�O‰OÕØ�)Š^Ø×Ñ˜_Õ-Ø�%‹ZØ %§
¡
ÑˆC��gØ×Ñ˜S 7™]¨SÑ0Õ1ð #ñ Ø�‰�r—w‘w˜yÓ)Ô*ÙØˆØ�9‰9�WÓÐr6   c                óF   — | j                  dd«      j                  dd«      S )NÚrž   rµ   ú\P©Úreplace©r2   s    r4   Úescape_dxf_line_endingsrÿ   N  s"   € ð �<‰<˜˜bÓ!×)Ñ)¨$°Ó6Ð6r6   c                ó8   ‡— dj                  ˆfd„| D «       «      S )Nrž   c              3  ó<   •K  — | ]  }t        |«      r‰n|–— Œ y ­wra   )Úis_non_printable_char)ri   rÓ   Úreplacements     €r4   rl   z3replace_non_printable_characters.<locals>.<genexpr>U  s   øè ø€ ÐPÉ4ÀaÔ"7¸Ô":‘;ÀÓAÉ4ùs   ƒ)rÃ   )r2   r  s    `r4   Ú replace_non_printable_charactersr  T  s   ø€ Ø�7‰7ÓPÉ4ÓPÓPÐPr6   c                óB   — dt        | «      cxk  xr dk  nc xr | dk7  S )Nr   é    Ú	)rÏ   )r¬   s    r4   r  r  X  s   € Ø”�D“	Ö˜BÔÒ/ 4¨4¡<Ð/r6   c                ó`  — | r| j                  «       rg S t        j                  d| «      }|D ��cg c]"  }t        j                  d|«      D ]  }|sŒ|‘Œ	 Œ$ }}}g }d}d}	|D ]’  }| }
|dk(  r|	rŒd}	|dk(  r"|j                  |j	                  «       «       d}Œ7|j                  «       r|s|
sŒL||z  }ŒR|�: |||z   «      |kD  r,|s||z  }Œj|j                  |j	                  «       «       |}d}	ŒŽ||z  }Œ” |r/|j                  «       s|j                  |j	                  «       «       |S c c}}w )aÆ  Wrap text at ``\n`` and given `box_width`. This tool was developed for
    usage with the MTEXT entity. This isn't the most straightforward word
    wrapping algorithm, but it aims to match the behavior of AutoCAD.

    Args:
        text: text to wrap, included ``\n`` are handled as manual line breaks
        box_width: wrapping length, ``None`` to just wrap at ``\n``
        get_text_width: callable which returns the width of the given string

    z(\n)z(\s+)rž   Frµ   T)ÚisspacerÕ   rÄ   r¿   Úrstrip)r2   Ú	box_widthÚget_text_widthÚmanual_linesÚlinerô   ÚtokensÚlinesÚcurrent_lineÚline_just_wrappedÚon_first_lines              r4   Ú	text_wrapr  \  s9  € ñ" �4—<‘<”>Øˆ	Ü—8‘8˜G TÓ*€LÙ(ÔP™L�D´"·(±(¸8ÀTÖ2J¨QÊaŠaÐ2Jˆa˜L€FÑPØ€EØ€LØÐãˆØ!˜	ˆØ�Š9Ñ*ØØ!ÐØ�Š9Ø�L‰L˜×,Ñ,Ó.Ô/Ø‰LØ�Y‰YŒ[Ùš}Ø Ñ!‘àÐ$©¸ÀqÑ8HÓ)IÈIÒ)UÙ#Ø  AÑ%‘Là—L‘L ×!4Ñ!4Ó!6Ô7Ø#$�LØ(,Ñ%à Ñ!‘ð) ñ, ˜L×0Ñ0Ô2Ø�‰�\×(Ñ(Ó*Ô+Ø€Lùó; Qs   ° D*ÁD*c                ó  — | j                  d«      st        | j                  «       › d�«      ‚| j                  rG| j                  j                  j                  | j                  j                  «      }|r|j                  S y)zhReturns ``True`` if the associated text :class:`~ezdxf.entities.Textstyle`
    is vertical stacked.
    Ústylez& does not support the style attribute.F)	Úis_supported_dxf_attribrš   r–   ÚdocÚstylesr˜   r—   r  Úis_vertical_stacked)r2   r  s     r4   Úis_text_vertical_stackedr  �  se   € ð ×'Ñ'¨Ô0Ü˜4Ÿ<™<›>Ð*Ð*PÐQÓRÐRà‡x‚xØ—‘—‘×#Ñ# D§H¡H§N¡NÓ3ˆÙØ×,Ñ,Ð,Ør6   rž   ÚlÚrrÓ   ÚjÚdÚ,Ú01234567890c                ó:   — t        | t        t        f«      r| d›S | S )NÚg)r8   r�   r   )rÚ   s    r4   Úrstrip0r$  «  s   € Ü�!”cœ5�\Ô"Ø�A�ˆØ€Hr6   c                  ó~   — e Zd ZU dZdZded<   dZded<   dZded<   ej                  Z
ded<    e«       Zd	ed
<   dd„Zy)ÚParagraphPropertiesa<  Stores all known MTEXT paragraph properties in a :class:`NamedTuple`.
    Indentations and tab stops are multiples of the default text height
    :attr:`MText.dxf.char_height`. E.g. :attr:`char_height` is 0.25 and
    :attr:`indent` is 4, the real indentation is 4 x 0.25 = 1 drawing unit.
    The default tabulator stops are 4, 8, 12, ... if no tabulator stops are
    explicit defined.

    Args:
         indent (float): left indentation of the first line, relative to :attr:`left`,
            which means an :attr:`indent` of 0 has always the same indentation
            as :attr:`left`
         left (float): left indentation of the paragraph except for the first line
         right (float): left indentation of the paragraph
         align: :class:`~ezdxf.lldxf.const.MTextParagraphAlignment` enum
         tab_stops: tuple of tabulator stops, as ``float`` or as ``str``,
            ``float`` values are left aligned tab stops, strings with prefix
            ``"c"`` are center aligned tab stops and strings with prefix ``"r"``
            are right aligned tab stops

    r   r   ÚindentÚleftÚrightr   ÚalignÚtupleÚ	tab_stopsc           	     ó>  — g }| j                   r4|j                  d| j                   d›�«       |j                  t        «       | j                  r4|j                  d| j                  d›�«       |j                  t        «       | j                  r4|j                  d| j                  d›�«       |j                  t        «       | j
                  r:|j                  dt        | j
                     › �«       |j                  t        «       | j                  rT|j                  dt        j                  t        t        | j                  «      «      › �«       |j                  t        «       |r3|d   t        k(  r|j                  «        dd	j                  |«      z   d
z   S y	)zdReturns the MTEXT paragraph properties as MTEXT inline code
        e.g. ``"\pxi-2,l2;"``.

        Úir#  r  r  Úqrô   rº   z\pxrž   r¹   )r'  r¿   ÚCOMMAr(  r)  r*  Ú_alignment_charr,  rÃ   Úmapr$  r½   )r1   Úargss     r4   ÚtostringzParagraphProperties.tostringÓ  s+  € ð
 ˆØ�;Š;Ø�K‰K˜!˜DŸK™K¨˜?Ð+Ô,Ø�K‰KœÔØ�9Š9Ø�K‰K˜!˜DŸI™I a˜=Ð)Ô*Ø�K‰KœÔØ�:Š:Ø�K‰K˜!˜DŸJ™J q˜>Ð*Ô+Ø�K‰KœÔØ�:Š:Ø�K‰K˜!œO¨D¯J©JÑ7Ð8Ð9Ô:Ø�K‰KœÔØ�>Š>Ø�K‰K˜!œEŸJ™J¤s¬7°D·N±NÓ'CÓDÐEÐFÔGØ�K‰KœÔáØ�B‰xœ5Ò Ø—‘”
à˜BŸG™G D›MÑ)¨CÑ/Ð/Ør6   N©r|   rz   )r„   r…   r†   r‡   r'  Ú__annotations__r(  r)  r   ÚDEFAULTr*  r+  r,  r4  rn   r6   r4   r&  r&  ±  sJ   … ñð, €FˆEÓØ€Dˆ%ƒOØ€Eˆ5ÓØ%<×%DÑ%D€EÐ"ÓDñ “w€IˆuÓôr6   r&  c                  ó  — e Zd ZdZd'd(d„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dZdZdZdZd)d„Zd)d„Zd*d„Zd„ Zd+d,d„Zd-d„Zd.d„Zd-d„Zd-d„Zd/d„Zd0d„Zd1d„Z d2d„Z!d3d4d„Z"d)d „Z#d)d!„Z$d)d"„Z%d)d#„Z&d5d$„Z'	 	 	 	 	 	 	 	 d6d%„Z(y&)7ÚMTextEditora  The :class:`MTextEditor` is a helper class to build MTEXT content
    strings with support for inline codes to change color, font or
    paragraph properties. The result is always accessible by the :attr:`text`
    attribute or the magic :func:`__str__` function as
    :code:`str(MTextEditor("text"))`.

    All text building methods return `self` to implement a floating interface::

        e = MTextEditor("This example ").color("red").append("switches color to red.")
        mtext = msp.add_mtext(str(e))

    The initial text height, color, text style and so on is determined by the
    DXF attributes of the :class:`~ezdxf.entities.MText` entity.

    .. warning::

        The :class:`MTextEditor` assembles just the inline code, which has to be
        parsed and rendered by the target CAD application, `ezdxf` has no influence
        to that result.

        Keep inline formatting as simple as possible, don't test the limits of its
        capabilities, this will not work across different CAD applications and keep
        the formatting in a logic manner like, do not change paragraph properties
        in the middle of a paragraph.

        **There is no official documentation for the inline codes!**

    Args:
        text: init value of the MTEXT content string.

    c                ó$   — t        |«      | _        y ra   )rz   r2   ©r1   r2   s     r4   r5   zMTextEditor.__init__  s   € Ü˜“Iˆ�	r6   rû   z\Nú\Lú\lú\Oú\oú\Kú\kÚ{Ú}z\A0;z\A1;z\A2;ú\~z^Ic                ó0   — | xj                   |z  c_         | S )zAppend `text`.rþ   r;  s     r4   r¿   zMTextEditor.append*  s   € à�	Š	�TÑ�	Øˆr6   c                ó0   — | xj                   |z  c_         | S )z}
        Append `text`::

            e = MTextEditor("First paragraph.\P")
            e += "Second paragraph.\P")

        rþ   r;  s     r4   Ú__iadd__zMTextEditor.__iadd__/  s   € ð 	�	Š	�TÑ�	Øˆr6   c                ó   — | j                   S )z1Returns the MTEXT content attribute :attr:`text`.rþ   rD   s    r4   Ú__str__zMTextEditor.__str__:  ó   € à�y‰yÐr6   c                ó   — d| _         y)z%Reset the content to an empty string.rž   Nrþ   rD   s    r4   ræ   zMTextEditor.clear>  s	   € àˆ�	r6   c           
     ó\   — | j                  d|› dt        |«      › dt        |«      › d�«      S )aÈ  Set the text font by the font family name. Changing the font height
        should be done by the :meth:`height` or the :meth:`scale_height` method.
        The font family name is the name shown in font selection widgets in
        desktop applications: "Arial", "Times New Roman", "Comic Sans MS".
        Switching the codepage is not supported.

        Args:
            name: font family name
            bold: flag
            italic: flag

        z\fz|bz|ir¹   ©r¿   r�   )r1   ÚnameÚboldÚitalics       r4   r3   zMTextEditor.fontB  s0   € ð& �{‰{˜b   b¬¨T«¨°2´c¸&³k°]À!ÐDÓEÐEr6   c                ó@   — | j                  dt        |d«      › d�«      S )aï  Scale the text height by a `factor`. This scaling will accumulate,
        which means starting at height 2.5 and scaling by 2 and again by 3 will
        set the text height to 2.5 x 2 x 3 = 15. The current text height is not
        stored in the :class:`MTextEditor`, you have to track the text height by
        yourself! The initial text height is stored in the
        :class:`~ezdxf.entities.MText` entity as DXF attribute
        :class:`~ezdxf.entities.MText.dxf.char_height`.

        ú\Hr    zx;©r¿   Úround©r1   Úfactors     r4   Úscale_heightzMTextEditor.scale_heightW  s$   € ð �{‰{˜b¤ v¨qÓ!1Ð 2°"Ð5Ó6Ð6r6   c                ó@   — | j                  dt        |d«      › d�«      S )z.Set the absolute text height in drawing units.rR  r    r¹   rS  )r1   rI   s     r4   rI   zMTextEditor.heightc  ó"   € à�{‰{˜b¤ v¨qÓ!1Ð 2°!Ð4Ó5Ð5r6   c                ó@   — | j                  dt        |d«      › d�«      S )z#Set the absolute text width factor.z\Wr    r¹   rS  rU  s     r4   Úwidth_factorzMTextEditor.width_factorg  rY  r6   c                ó@   — | j                  dt        |d«      › d�«      S )z+Set the absolute character tracking factor.z\Tr    r¹   rS  rU  s     r4   Úchar_tracking_factorz MTextEditor.char_tracking_factork  rY  r6   c                ó>   — | j                  dt        |«      › d�«      S )z€Set the text oblique angle in degrees, vertical is 0, a value of 15
        will lean the text 15 degree to the right.

        z\Qr¹   rM  )r1   rV   s     r4   r^   zMTextEditor.obliqueo  s    € ð
 �{‰{˜b¤ U£ ¨AÐ.Ó/Ð/r6   c                ób   — | j                  t        j                  |j                  «          «      S )zsSet the text color by color name: "red", "yellow", "green", "cyan",
        "blue", "magenta" or "white".

        )Úacir   ÚMTEXT_COLOR_INDEXr§   )r1   rN  s     r4   ÚcolorzMTextEditor.colorv  s$   € ð
 �x‰xœ×/Ñ/°·
±
³Ñ=Ó>Ð>r6   c                ór   — d|cxk  rdk  r"n t        d«      ‚| j                  d|› d�«      S t        d«      ‚)z3Set the text color by :ref:`ACI` in range [0, 256].r   é   z\Cr¹   zaci not in range [0, 256])r¿   Ú
ValueError©r1   r`  s     r4   r`  zMTextEditor.aci}  s>   € à�Œ?�sŒ?äÐ4Ó5Ð5ð —;‘; " S E¨˜|Ó,Ð,ÜÐ4Ó5Ð5r6   c                óP   — |\  }}}| j                  dt        |||f«      › d�«      S )z Set the text color as RGB value.z\cr¹   )r¿   r   )r1   Úrgbr  r#  Úbs        r4   rh  zMTextEditor.rgbƒ  s1   € à‰ˆˆ1ˆaØ�{‰{˜b¤¨!¨Q°¨Ó!3Ð 4°AÐ6Ó7Ð7r6   c                ól   — |dvrt        d|› �«      ‚|dk(  r|dz  }| j                  d|› |› |› d�«      S )a"  Append stacked text `upr` over `lwr`, argument `t` defines the
        kind of stacking, the space " " after the "^" will be added
        automatically to avoid caret decoding:

        .. code-block:: none

            "^": vertical stacked without divider line, e.g. \SA^ B:
                 A
                 B

            "/": vertical stacked with divider line,  e.g. \SX/Y:
                 X
                 -
                 Y

            "#": diagonal stacked, with slanting divider line, e.g. \S1#4:
                 1/4

        ú^/#zinvalid type symbol: rØ   r·   z\Sr¹   )re  r¿   )r1   rõ   rö   rô   s       r4   rì   zMTextEditor.stackˆ  sN   € ð( �E‰>ÜÐ4°Q°CÐ8Ó9Ð9à�Š8Ø�‰HˆAØ�{‰{˜b   a S¨¨¨QÐ/Ó0Ð0r6   c                ó,   — | j                  d|› d�«      S )z•Group `text`, all properties changed inside a group are reverted at
        the end of the group. AutoCAD supports grouping up to 8 levels.

        rB  rC  ©r¿   r;  s     r4   rÐ   zMTextEditor.group£  s   € ð
 �{‰{˜R ˜v R˜=Ó)Ð)r6   c                ó,   — | j                  d|› d�«      S )z)Append `text` with a line below the text.r<  r=  rm  r;  s     r4   Ú	underlinezMTextEditor.underlineª  ó   € à�{‰{˜b   b˜>Ó*Ð*r6   c                ó,   — | j                  d|› d�«      S )z)Append `text` with a line above the text.r>  r?  rm  r;  s     r4   ÚoverlinezMTextEditor.overline®  rp  r6   c                ó,   — | j                  d|› d�«      S )z+Append `text` with a line through the text.r@  rA  rm  r;  s     r4   Ústrike_throughzMTextEditor.strike_through²  rp  r6   c                ó@   — | j                  |j                  «       «      S )zBSet paragraph properties by a :class:`ParagraphProperties` object.)r¿   r4  )r1   Úpropss     r4   ré   zMTextEditor.paragraph¶  s   € à�{‰{˜5Ÿ>™>Ó+Ó,Ð,r6   c           	     óò   ‡ — t        «       j                  t        | dz  ||f¬«      «      }|j                  dj	                  ˆ fd„t        ||«      D «       «      «       ‰ j                  t        |«      «      S )u/  Build bulleted lists by utilizing paragraph indentation and a
        tabulator stop. Any string can be used as bullet. Indentation is
        a multiple of the initial MTEXT char height (see also docs about
        :class:`ParagraphProperties`), which means indentation in
        drawing units is :attr:`MText.dxf.char_height` x `indent`.

        Useful UTF bullets:

        - "bull" U+2022 = â€¢ (Alt Numpad 7)
        - "circle" U+25CB = â—‹ (Alt Numpad 9)

        For numbered lists just use numbers as bullets::

            MTextEditor.bullet_list(
                indent=2,
                bullets=["1.", "2."],
                content=["first", "second"],
            )

        Args:
            indent: content indentation as multiple of the initial MTEXT char height
            bullets: iterable of bullet strings, e.g. :code:`["-"] * 3`,
                for 3 dashes as bullet strings
            content: iterable of list item strings, one string per list item,
                list items should not contain new line or new paragraph commands.

        g      è?)r'  r(  r,  rž   c              3  ób   •K  — | ]&  \  }}|‰j                   z   |z   ‰j                  z   –— Œ( y ­wra   )ÚTABÚNEW_PARAGRAPH)ri   ri  rÓ   r1   s      €r4   rl   z*MTextEditor.bullet_list.<locals>.<genexpr>à  s2   øè ø€ ð ÙBW¹$¸!¸Q��D—H‘H‘˜qÑ  4×#5Ñ#5Õ5ÑBWùs   ƒ,/)r9  ré   r&  r¿   rÃ   ÚziprÐ   rz   )r1   r'  Úbulletsrè   Úitemss   `    r4   Úbullet_listzMTextEditor.bullet_listº  ss   ø€ ô< “×'Ñ'ÜØ�w ‘~ØØ!˜)ôó
ˆð 	�‰Ø�G‰Gó ÜBEÀgÈwÔBWóó ô	
ð
 �z‰zœ#˜e›*Ó%Ð%r6   N)rž   ©r2   rz   )r2   rz   r|   r9  r5  )FF)rN  rz   rO  ÚboolrP  r€  r|   r9  )rV  r   r|   r9  )rI   r   r|   r9  )rV   r�   r|   r9  )rN  rz   r|   r9  )r`  r�   r|   r9  )rh  r   r|   r9  )rØ   )rõ   rz   rö   rz   rô   rz   r|   r9  )rv  r&  r|   r9  )r'  r   r|  úIterable[str]rè   r�  r|   r9  ))r„   r…   r†   r‡   r5   ÚNEW_LINErz  Ú
NEW_COLUMNÚUNDERLINE_STARTÚUNDERLINE_STOPÚOVERSTRIKE_STARTÚOVERSTRIKE_STOPÚSTRIKE_STARTÚSTRIKE_STOPÚGROUP_STARTÚ	GROUP_ENDÚALIGN_BOTTOMÚALIGN_MIDDLEÚ	ALIGN_TOPÚNBSPry  r¿   rG  rI  ræ   r3   rW  rI   r[  r]  r^   rb  r`  rh  rì   rÐ   ro  rr  rt  ré   r~  rn   r6   r4   r9  r9  õ  så   „ ñô@ð €HØ€MØ€JØ€OØ€NØÐØ€OØ€LØ€KØ€KØ€IØ€LØ€LØ€IØ€DØ
€Cóó
	óòôFó*
7ó6ó6ó6ó0ó?ó6ó8ô
1ó6*ó+ó+ó+ó-ð*&Øð*&Ø&3ð*&Ø>Kð*&à	ô*&r6   r9  c                  ó   — e Zd Zy)ÚUnknownCommandN)r„   r…   r†   rn   r6   r4   r‘  r‘  ç  s   „ Ør6   r‘  c                  ó.  — e Zd ZdZdd„Zdd„ZeZd„ Zdd„Ze	dd„«       Z
e
j                  dd„«       Z
ddd„Ze	dd	„«       Zej                  dd
„«       Ze	dd„«       Zej                  dd„«       Ze	dd„«       Zej                  dd„«       Ze	dd„«       Zy)ÚMTextContextz0Internal class to store the MTEXT context state.c                óô   — ddl m} d| _        d| _        d| _        d | _        t        j                  | _         |j                  «       | _
        d| _        d| _        d| _        d| _        t        «       | _        y )Nr   r%   Fé   r+   r‹   )Úezdxf.fontsr&   Ú_strokeÚcontinue_strokeÚ_acirh  r   ÚBOTTOMr*  ÚFontFaceÚ	font_facer�   r[  r]  r^   r&  ré   )r1   r&   s     r4   r5   zMTextContext.__init__î  sg   € Ý%àˆŒØ%*ˆÔØˆŒ	Ø"&ˆŒÜ'×.Ñ.ˆŒ
Ø'˜Ÿ™Ó)ˆŒØ!$ˆŒØ#&ˆÔØ+.ˆÔ!Ø!ˆŒÜ,Ó.ˆ�r6   c                ó�  — t        «       }| j                  |_        | j                  |_        | j                  |_        | j                  |_        | j
                  |_        | j                  |_        | j                  |_        | j                  |_        | j                  |_	        | j                  |_
        | j                  |_        |S ra   )r“  r—  r˜  r™  rh  r*  rœ  r�   r[  r]  r^   ré   )r1   Úps     r4   Ú__copy__zMTextContext.__copy__ý  s�   € Ü‹NˆØ—L‘LˆŒ	Ø ×0Ñ0ˆÔØ—‘ˆŒØ—‘ˆŒØ—*‘*ˆŒØ—n‘nˆŒØ—‘ˆŒØ×*Ñ*ˆŒØ!%×!:Ñ!:ˆÔØ—L‘LˆŒ	Ø—n‘nˆŒØˆr6   c                ó
  — t        | j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  | j                  | j                  f«      S ra   )Úhashr—  r˜  r™  rh  r*  rœ  r�   r[  r]  r^   ré   rD   s    r4   Ú__hash__zMTextContext.__hash__  sg   € Üà—‘Ø×$Ñ$Ø—	‘	Ø—‘Ø—
‘
Ø—‘Ø—‘Ø×!Ñ!Ø×)Ñ)Ø—‘Ø—‘ðó
ð 	
r6   c                ó0   — t        | «      t        |«      k(  S ra   )r¡  )r1   Úothers     r4   Ú__eq__zMTextContext.__eq__  s   € Ü�D‹zœT %›[Ñ(Ð(r6   c                ó   — | j                   S ra   )r™  rD   s    r4   r`  zMTextContext.aci"  rJ  r6   c                óf   — d|cxk  rdk  rn t        d«      ‚|| _         d | _        y t        d«      ‚)Nr   rd  zaci not in range[0,256])r™  rh  re  rf  s     r4   r`  zMTextContext.aci&  s7   € à�Œ?�sŒ?ô Ð6Ó7Ð7ð ˆDŒIØˆD�HäÐ6Ó7Ð7r6   c                ó`   — |r| xj                   |z  c_         y| xj                   | z  c_         y)z´Set/clear binary `stroke` flag in `self._stroke`.

        Args:
            stroke: set/clear stroke flag
            state: ``True`` for setting, ``False`` for clearing

        N)r—  )r1   ÚstrokeÚstates      r4   Ú_set_stroke_statezMTextContext._set_stroke_state.  s%   € ñ Ø�LŠL˜FÑ"ŽLà�LŠL˜V˜GÑ#ŽLr6   c                óN   — t        | j                  t        j                  z  «      S ra   )r€  r—  r   Ú	UNDERLINErD   s    r4   ro  zMTextContext.underline;  s   € ä�D—L‘L¤;×#8Ñ#8Ñ8Ó9Ð9r6   c                óD   — | j                  t        j                  |«       y ra   )r«  r   r­  ©r1   Úvalues     r4   ro  zMTextContext.underline?  s   € à×Ñœ{×4Ñ4°eÕ<r6   c                óN   — t        | j                  t        j                  z  «      S ra   )r€  r—  r   ÚSTRIKE_THROUGHrD   s    r4   rt  zMTextContext.strike_throughC  s   € ä�D—L‘L¤;×#=Ñ#=Ñ=Ó>Ð>r6   c                óD   — | j                  t        j                  |«       y ra   )r«  r   r²  r¯  s     r4   rt  zMTextContext.strike_throughG  s   € à×Ñœ{×9Ñ9¸5ÕAr6   c                óN   — t        | j                  t        j                  z  «      S ra   )r€  r—  r   ÚOVERLINErD   s    r4   rr  zMTextContext.overlineK  s   € ä�D—L‘L¤;×#7Ñ#7Ñ7Ó8Ð8r6   c                óD   — | j                  t        j                  |«       y ra   )r«  r   rµ  r¯  s     r4   rr  zMTextContext.overlineO  s   € à×Ñœ{×3Ñ3°UÕ;r6   c                ó,   — t        | j                  «      S ra   )r€  r—  rD   s    r4   Úhas_any_strokezMTextContext.has_any_strokeS  s   € ä�D—L‘LÓ!Ð!r6   N©r|   r}   )r|   r“  ©r|   r€  ©r|   r�   )r`  r�   )T)r©  r   rª  r€  r|   r}   )r°  r€  r|   r}   )r„   r…   r†   r‡   r5   rŸ  rÁ   r¢  r¥  rˆ   r`  Úsetterr«  ro  rt  rr  r¸  rn   r6   r4   r“  r“  ë  sï   „ Ù:ó/óð €Dò
ó")ð òó ðð 	‡Z�Zò8ó ð8ô$ð ò:ó ð:ð ×Ñò=ó ð=ð ò?ó ð?ð ×ÑòBó ðBð ò9ó ð9ð ‡_�_ò<ó ð<ð ò"ó ñ"r6   r“  c                  ó–   — e Zd ZdZdd„Zedd„«       Zedd„«       Zdd„Zddd„Z	ddd„Z
ddd„Zddd	„Zddd
„Zdd„Zdd„Zdd„Zdd„Zy)r¢   )Ú_textÚ	_text_lenÚ_indexc                óf   — t        |«      | _        t        | j                  «      | _        d| _        y )Nr   )rz   r¾  rÙ   r¿  rÀ  r;  s     r4   r5   zTextScanner.__init__[  s#   € Ü˜“YˆŒ
Ü˜TŸZ™Z›ˆŒØˆ�r6   c                ó4   — | j                   | j                  k\  S ra   ©rÀ  r¿  rD   s    r4   Úis_emptyzTextScanner.is_empty`  s   € à�{‰{˜dŸn™nÑ,Ð,r6   c                ó4   — | j                   | j                  k  S ra   rÃ  rD   s    r4   r¥   zTextScanner.has_datad  s   € à�{‰{˜TŸ^™^Ñ+Ð+r6   c                ó‚   — 	 | j                   | j                     }| xj                  dz  c_        |S # t        $ r Y yw xY w)NrN   rž   ©r¾  rÀ  r¾   )r1   r¬   s     r4   r˜   zTextScanner.geth  sB   € ð	Ø—:‘:˜dŸk™kÑ*ˆDØ�KŠK˜1Ñ�Kð ˆøô ò 	Ùð	ús   ‚.2 ²	>½>c                óN   — |dk  rt        |«      ‚| xj                  |z  c_        y )NrN   )re  rÀ  ©r1   Úcounts     r4   r©   zTextScanner.consumep  s"   € Ø�1Š9Ü˜UÓ#Ð#Ø�Š�uÑŽr6   c                ó.   — | xj                   |z  c_         y)zconsume() without safety checkN©rÀ  rÉ  s     r4   Úfast_consumezTextScanner.fast_consumeu  s   € à�Š�uÑŽr6   c                óz   — |dk  rt        |«      ‚	 | j                  | j                  |z      S # t        $ r Y yw xY w)Nr   rž   )re  r¾  rÀ  r¾   ©r1   Úoffsets     r4   r¦   zTextScanner.peeky  sC   € Ø�AŠ:Ü˜VÓ$Ð$ð	Ø—:‘:˜dŸk™k¨FÑ2Ñ3Ð3øÜò 	Ùð	ús   ’. ®	:¹:c                óZ   — 	 | j                   | j                  |z      S # t        $ r Y yw xY w)zpeek() without safety checkrž   rÇ  rÏ  s     r4   Ú	fast_peekzTextScanner.fast_peek�  s1   € ð	Ø—:‘:˜dŸk™k¨FÑ2Ñ3Ð3øÜò 	Ùð	ús   ‚ ž	*©*c                ó^  — | j                  | j                  | j                  d «      }|j                  ry|j	                  «       }|r+|dk(  r&|j	                  d«      |k(  r|j                  d«       ŒI||k(  r| j                  |j                  z   S |j                  d«       |j                  rŒyy)at  Return the index of the next `char`. If `escape` is True, backslash
        escaped `chars` will be ignored e.g. "\;;" index of the next ";" is 1
        if `escape` is False and 2 if `escape` is True. Returns -1 if `char`
        was not found.

        Args:
            char: single letter as string
            escape: ignore backslash escaped chars if True.

        Nr²   rN   rŽ   rº   )Ú	__class__r¾  rÀ  r¥   r¦   r©   )r1   r¬   Úescaper«   rÓ   s        r4   ÚfindzTextScanner.findˆ  s’   € ð —.‘. §¡¨D¯K©K¨MÐ!:Ó;ˆØ×ÒØ—‘“ˆAÙ˜!˜tš)¨¯©°Q«¸4Ò(?Ø—‘ Ô"ØØ�DŠyØ—{‘{ W§^¡^Ñ3Ð3Ø�O‰O˜AÔð ×Óð r6   c                óh   — || j                   k  rt        |«      ‚| j                  | j                   | S )zCReturns the substring from the current location until index < stop.)rÀ  r¾   r¾  )r1   Ústops     r4   ÚsubstrzTextScanner.substrŸ  s.   € à�$—+‘+ÒÜ˜TÓ"Ð"Ø�z‰z˜$Ÿ+™+¨Ð-Ð-r6   c                ó4   — | j                   | j                  d S )z,Returns the unprocessed part of the content.N)r¾  rÀ  rD   s    r4   ÚtailzTextScanner.tail¥  s   € à�z‰z˜$Ÿ+™+˜-Ð(Ð(r6   c                ó   — | j                   S ra   rÌ  rD   s    r4   ÚindexzTextScanner.index©  s   € Ø�{‰{Ðr6   c                ó    — | j                   || S ra   )r¾  )r1   ÚstartrØ  s      r4   Úsubstr2zTextScanner.substr2¬  s   € Ø�z‰z˜% Ð%Ð%r6   Nr  rº  r5  )rN   )rÊ  r�   r|   r}   )r   )rÐ  r�   r|   rz   ©F)r¬   rz   r|   r�   )rØ  r�   r|   rz   r»  )rß  r�   rØ  r�   r|   rz   )r„   r…   r†   Ú	__slots__r5   rˆ   rÄ  r¥   r˜   r©   rÍ  r¦   rÒ  rÖ  rÙ  rÛ  rÝ  rà  rn   r6   r4   r¢   r¢   X  sf   „ Ø0€Ióð
 ò-ó ð-ð ò,ó ð,óôô
ôôôó..ó)óô&r6   r¢   c                  ó4   — e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
Zy)râ   r   rN   rŽ   r    r'   é   é   r•  é   é	   N)r„   r…   r†   ÚNONEÚWORDÚSTACKÚSPACEr�  Ú	TABULATORrz  rƒ  ÚWRAP_AT_DIMLINEÚPROPERTIES_CHANGEDrn   r6   r4   râ   râ   °  s5   „ Ø€DØ€DØ€EØ€EØ€DØ€IØ€MØ€JØ€OØÑr6   râ   c                  ó   — e Zd ZdZddd„Zy)Ú
MTextToken©rä   Úctxrå   Nc                ó.   — || _         || _        || _        y ra   rñ  )r1   rô   rò  rå   s       r4   r5   zMTextToken.__init__À  s   € Ø ˆŒ	Ø!$ˆŒØˆ�	r6   ra   )rô   râ   rò  r“  )r„   r…   r†   râ  r5   rn   r6   r4   rð  rð  ½  s   „ Ø'€Iõr6   rð  z#[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?z)[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?([x]?))r  r  rÓ   r  r  c                  óÆ   — e Zd ZdZ	 	 d	 	 	 dd„Zdd„Zdd„Zdd„Zdd„Zdd„Z	dd	„Z
dd
„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zd d!d„Zd!d„Zd d!d„Zdd„Zdd„Zd„ Zy)"rã   a  Parses the MText content string and yields the content as tokens and
    the current MText properties as MTextContext object. The context object is
    treated internally as immutable object and should be treated by the client
    the same way.

    The parser works as iterator and yields MTextToken objects.

    Args:
        content: MText content string
        ctx: initial MText context
        yield_property_commands: yield commands that change properties or context,
            default is ``False``

    Nc                ó˜   — |€
t        «       }|| _        t        t        |«      «      | _        g | _        d| _        t        |«      | _        y ©NF)	r“  rò  r¢   r¤   r«   Ú
_ctx_stackÚ_continue_stroker€  Ú_yield_property_commands)r1   rè   rò  Úyield_property_commandss       r4   r5   zMTextParser.__init__â  sE   € ð ˆ;Ü“.ˆCØˆŒÜ"¤<°Ó#8Ó9ˆŒØ.0ˆŒØ %ˆÔÜ(,Ð-DÓ(EˆÕ%r6   c                ó"   — | j                  «       S ra   )ÚparserD   s    r4   Ú__iter__zMTextParser.__iter__ð  s   € Ø�z‰z‹|Ðr6   c                óN   — | j                   j                  | j                  «       y ra   )r÷  r¿   rò  rD   s    r4   Úpush_ctxzMTextParser.push_ctxó  s   € Ø�‰×Ñ˜tŸx™xÕ(r6   c                ó\   — | j                   r | j                   j                  «       | _        y y ra   )r÷  r½   rò  rD   s    r4   Úpop_ctxzMTextParser.pop_ctxö  s"   € Ø�?Š?Ø—‘×*Ñ*Ó,ˆD�Hð r6   c              #  óX  ‡ ‡‡‡‡‡‡	‡
K  — ‰ j                   Š‰j                  Š‰j                  Šd Št        j                  Št        j
                  Š
ˆˆˆ
fd„Š	dˆˆˆˆ ˆˆ	ˆ
fd„}	  |«       \  }}|r7t        |‰ j                  |«      –— ‰rt        ‰‰ j                  d «      –— d Šny ŒE­w)Nc                ó*   •—  ‰«        | r|Š‰| fS |d fS ra   rn   )rë   ró   r©   Úfollowup_tokenÚ
word_tokens     €€€r4   Úword_and_tokenz)MTextParser.parse.<locals>.word_and_token  s%   ø€ áŒIÙØ!&�Ø! 4Ð'Ð'Ø˜$�;Ðr6   c                 óÈ  •— d} ‰	j                   �r#d} ‰«       }‰	j                  «       }|dk(  rû ‰d«      dv rd} ‰«         ‰«       }nà| r‰| fS  ‰«        ‰	j                  «       }|dk(  rt        j                  d fS |dk(  rt        j
                  d fS |d	k(  rt        j                  d fS |d
k(  rt        j                  d fS |dk(  r‰
j                  «       S |rN	 ‰
j                  |«       ‰
j                  r0t        j                  ‰	j                  |‰	j                  «       «      fS �Œ&|dk  r;|dk(  r ‰| t        j                  «      S |dk(  r ‰| t        j
                  «      S d}nQ|dk(  rL ‰d«      dk(  rA ‰d«      j                  «       }t         j"                  j                  |«      }|r
 ‰d«       |}|dk(  r	 ‰| ‰«      S |sJ|dk(  r | r‰| fS  ‰d«       ‰
j%                  «        �Œì|dk(  r | r‰| fS  ‰d«       ‰
j'                  «        �Œ ‰«        |dk\  r| |z  } ‰	j                   r�Œ#| r‰| fS t        j(                  d fS # t        $ r | ||z   z  } Y �Œ8w xY w)Nrž   Fr²   rN   r³   TÚ~r´   r¶   ÚXr¸   r·   r  rµ   rŸ   rŽ   rB  rC  )r¥   rÝ  r˜   râ   r�  rz  rƒ  rí  Úparse_stackingÚparse_propertiesrù  rî  rà  r‘  rì  r§   r   r¨   rÿ  r  rè  )rë   rÕ  r®   Úcmd_start_indexÚcmdr­   Úspecial_charr©   r¦   r«   r1   Úspace_tokenr  r  s          €€€€€€€r4   Ú
next_tokenz%MTextParser.parse.<locals>.next_token  s�  ø€ àˆDØ×"Ó"Ø�Ù›�Ø")§-¡-£/�Ø˜T’>á˜A“w &Ñ(Ø!%˜Ùœ	Ù!%£™ñ  à#-¨tÐ#3Ð3Ùœ	Ø%Ÿk™k›m˜Ø #š:Ü#,§>¡>°4Ð#7Ð7Ø #š:Ü#,×#:Ñ#:¸DÐ#@Ð@Ø #š:Ü#,×#7Ñ#7¸Ð#=Ð=Ø #š:Ü#,×#<Ñ#<¸dÐ#BÐBØ #š:Ø#'×#6Ñ#6Ó#8Ð8Ùð&Ø $× 5Ñ 5°cÔ :ð
 $(×#@Ò#@ä(1×(DÑ(DØ(/¯©Ø,;¸W¿]¹]»_ó)*ð,&ð %&ñ !ð ˜C’<Ø ’~Ù-¨d´I×4GÑ4GÓHÐHØ ’~Ù-¨d´I×4KÑ4KÓLÐLà ‘FØ˜s’]¡t¨A£w°#¢~Ù ›7Ÿ=™=›?�DÜ#(×#>Ñ#>×#BÑ#BÀ4Ó#H�LÙ#Ù œ
Ø!-˜à˜S’=Ù)¨$°Ó<Ð<áØ ’}ÙØ#-¨tÐ#3Ð3á# AœJØ ŸM™MœOÙ$Ø 3šÙØ#-¨tÐ#3Ð3á# AœJØ ŸL™LœNÙ$ñ ”	Ø˜S’=Ø˜F‘N�Dða ×"Ô"ñd Ø! 4Ð'Ð'ä —~‘~ tÐ+Ð+øôo $2ò 5à $¨°©Ñ 4£ð5ús   ÃI ÉI!É I!©r|   ztuple[TokenType, Any])r«   rÍ  rÒ  râ   rë  ré  rð  rò  )r1   r  Útype_rå   r©   r  r¦   r«   r  r  r  s   `   @@@@@@@r4   rü  zMTextParser.parseú  sš   ÿè ø€ ð —,‘,ˆØ×&Ñ&ˆØ× Ñ ˆØ.2ˆÜ—o‘oˆÜ—^‘^ˆ
ö	÷X	,ó X	,ðt Ù$›,‰KˆE�4ÙÜ  ¨¯©°$Ó7Ò7Ù!Ü$ ^°T·X±X¸tÓDÒDØ%)‘Nàð ùs   ŠB B*c                óÄ   ‡‡‡— ˆfd„Šˆˆfd„Šdˆˆfd„}d	ˆˆfd„}t        | j                  d¬«      «      Š |«       \  }}|r |«       nd}t        j                  |||ffS )
aÊ  Returns a tuple of strings: (numerator, denominator, type).
        The numerator and denominator is always a single and can contain spaces,
        which are not decoded as separate tokens. The type string is "^" for
        a limit style fraction without a line, "/" for a horizontal fraction
        and "#" for a diagonal fraction. If the expression does not contain
        any stacking type char, the type and denominator string are empty "".

        c                 óH   •— ‰j                  «       } t        | «      dk  rd} | S )Nr  r·   )r¦   rÏ   )rÓ   Ústacking_scanners    €r4   Ú	peek_charz-MTextParser.parse_stacking.<locals>.peek_charz  s&   ø€ Ø ×%Ñ%Ó'ˆAÜ�1‹v˜Š{Ø�ØˆHr6   c                 ó~   •— d}  ‰«       }|dk(  rd} ‰j                  d«        ‰«       }‰j                  d«       || fS )NFr²   TrN   )r©   )rÕ  rÓ   r  r  s     €€r4   Úget_next_charz1MTextParser.parse_stacking.<locals>.get_next_char€  sH   ø€ ØˆFÙ“ˆAà�DŠyØ�Ø ×(Ñ(¨Ô+Ù“K�Ø×$Ñ$ QÔ'Ø�f�9Ðr6   c                 ót   •— d} ‰j                   r& ‰«       \  }}|s|dv r| |fS | |z  } ‰j                   rŒ&| dfS )Nrž   rk  ©r¥   )rë   rÓ   rÕ  r  r  s      €€r4   Úparse_numeratorz3MTextParser.parse_stacking.<locals>.parse_numerator‹  sM   ø€ ØˆDØ"×+Ò+Ù)›O‘	��6Ù ! u¡*Ø ˜7�NØ˜‘	�ð	 #×+Ó+ð
 ˜�8ˆOr6   c                 óX   •— d} ‰j                   r|  ‰«       d   z  } ‰j                   rŒ| S )Nrž   r   r  )rë   r  r  s    €€r4   Úparse_denominatorz5MTextParser.parse_stacking.<locals>.parse_denominator”  s2   ø€ ØˆDØ"×+Ò+Ø™›¨Ñ*Ñ*�ð #×+Ó+àˆKr6   T©rÕ  rž   )r|   ztuple[str, str]r5  )r¢   Úextract_expressionrâ   rê  )	r1   r  r  Ú	numeratorÚstacking_typeÚdenominatorr  r  r  s	         @@@r4   r
  zMTextParser.parse_stackingp  sb   ú€ ô	õ		ö	ö	ô ' t×'>Ñ'>ÀdÐ'>Ó'KÓLÐÙ#2Ó#4Ñ ˆ	�=Ù-:Ñ'Ô)ÀˆÜ�‰ ¨K¸Ð GÐGÐGr6   c                ór  — | j                   j                  «       }|dk(  rd|_        d| _        �np|dk(  rd|_        |j                  �sWd| _        �nN|dk(  rd|_        d| _        �n9|dk(  rd|_        |j                  �s d| _        �n|dk(  rd|_        d| _        �n|dk(  rd|_        |j                  sêd| _        nâ|d	k(  r| j                  |«       nË|d
k(  r| j                  |«       n´|dk(  r| j                  |«       n�|dk(  r| j                  |«       n†|dk(  r| j                  |«       no|dk(  r| j                  |«       nX|dk(  r| j                  |«       nA|dk(  r| j                  |«       n*|dk(  s|dk(  r| j                  |«       nt!        d|› �«      ‚| j                  |_        || _         y )NÚLTr  FÚOÚoÚKÚkÚAÚCrÓ   ÚHÚWÚQÚTrž  ÚfÚFzunknown command: )rò  rÁ   ro  rø  r¸  rr  rt  Úparse_alignÚparse_aci_colorÚparse_rgb_colorÚparse_heightÚparse_widthÚparse_obliqueÚparse_char_trackingÚparse_paragraph_propertiesÚparse_font_propertiesr‘  r˜  )r1   r  Únew_ctxs      r4   r  zMTextParser.parse_propertiesŸ  s£  € ð —(‘(—-‘-“/ˆØ�#Š:Ø $ˆGÔØ$(ˆDÖ!Ø�CŠZØ %ˆGÔØ×)Ó)Ø(-�Ö%Ø�CŠZØ#ˆGÔØ$(ˆDÖ!Ø�CŠZØ$ˆGÔØ×)Ó)Ø(-�Ö%Ø�CŠZØ%)ˆGÔ"Ø$(ˆDÖ!Ø�CŠZØ%*ˆGÔ"Ø×)Ò)Ø(-�Õ%Ø�CŠZØ×Ñ˜WÕ%Ø�CŠZØ× Ñ  Õ)Ø�CŠZØ× Ñ  Õ)Ø�CŠZØ×Ñ˜gÕ&Ø�CŠZØ×Ñ˜WÕ%Ø�CŠZØ×Ñ˜wÕ'Ø�CŠZØ×$Ñ$ WÕ-Ø�CŠZØ×+Ñ+¨GÕ4Ø�CŠZ˜3 #š:Ø×&Ñ& wÕ/ä Ð#4°S°EÐ!:Ó;Ð;Ø"&×"7Ñ"7ˆÔØˆ�r6   c                ó¾   — | j                   j                  «       }|dv rt        t        |«      «      |_        nt        j
                  |_        | j                  «        y )NÚ012)r«   r˜   r   r�   r*  rš  Úconsume_optional_terminator)r1   rò  r¬   s      r4   r1  zMTextParser.parse_alignÏ  sD   € Ø�|‰|×ÑÓ!ˆØ�5‰=Ü*¬3¨t«9Ó5ˆC�Iä*×1Ñ1ˆCŒIØ×(Ñ(Õ*r6   c                ód   — | j                  |j                  «      |_        | j                  «        y ra   )Úparse_float_value_or_factorr�   r=  ©r1   rò  s     r4   r4  zMTextParser.parse_height×  s$   € Ø×9Ñ9¸#¿.¹.ÓIˆŒØ×(Ñ(Õ*r6   c                ód   — | j                  |j                  «      |_        | j                  «        y ra   )r?  r[  r=  r@  s     r4   r5  zMTextParser.parse_widthÛ  s'   € Ø×;Ñ;¸C×<LÑ<LÓMˆÔØ×(Ñ(Õ*r6   c                ód   — | j                  |j                  «      |_        | j                  «        y ra   )r?  r]  r=  r@  s     r4   r7  zMTextParser.parse_char_trackingß  s,   € Ø#'×#CÑ#CØ×$Ñ$ó$
ˆÔ ð 	×(Ñ(Õ*r6   c                ó´   — | j                  d¬«      }|rC|j                  d«      rt        |d d «      }|t        |«      z  }|S t        t        |«      «      }|S )NT©Úrelativerg   rº   )Úextract_float_expressionÚendswithr   Úabs)r1   r°  ÚexprrV  s       r4   r?  z'MTextParser.parse_float_value_or_factorå  s^   € Ø×,Ñ,°dÐ,Ó;ˆÙØ�}‰}˜SÔ!Ü˜t C R˜yÓ)�Øœ˜V›Ñ$�ð ˆô œE $›KÓ(�Øˆr6   c                ól   — | j                  d¬«      }|rt        |«      |_        | j                  «        y )NFrD  )rF  r   r^   r=  )r1   rò  Úoblique_exprs      r4   r6  zMTextParser.parse_obliqueï  s0   € Ø×4Ñ4¸eÐ4ÓDˆÙÜ Ó-ˆCŒKØ×(Ñ(Õ*r6   c                ó„   — | j                  «       }|rt        |«      }|dk  r||_        d |_        | j	                  «        y )Ni  )Úextract_int_expressionr�   r`  rh  r=  )r1   rò  Úaci_exprr`  s       r4   r2  zMTextParser.parse_aci_colorõ  s=   € Ø×.Ñ.Ó0ˆÙÜ�h“-ˆCØ�SŠyØ�”Ø�”Ø×(Ñ(Õ*r6   c                ó¢   — | j                  «       }|r-t        t        |«      dz  «      \  }}}t        |||«      |_        | j                  «        y )Niÿÿÿ )rM  r    r�   r   rh  r=  )r1   rò  Úrgb_exprri  r#  r  s         r4   r3  zMTextParser.parse_rgb_colorþ  sG   € Ø×.Ñ.Ó0ˆÙäœc (›m¨hÑ6Ó7‰GˆAˆq�!Ü˜!˜Q “lˆCŒGØ×(Ñ(Õ*r6   c                óð   — d}| j                   j                  «       }|rt        nt        }t	        j
                  ||«      }|r3|j                  «       \  }}||| }| j                   j                  |«       |S ©Nrž   )r«   rÛ  Ú
RE_FLOAT_XÚRE_FLOATrÕ   rÒ   Úspanr©   )r1   rE  rª   rÛ  ÚpatternrÒ   rß  Úends           r4   rF  z$MTextParser.extract_float_expression  sf   € ØˆØ�|‰|× Ñ Ó"ˆÙ (•*¬hˆÜ—‘˜ $Ó'ˆÙØŸ™›‰JˆE�3Ø˜% �_ˆFØ�L‰L× Ñ  Ô%Øˆr6   c                óÔ   — d}| j                   j                  «       }t        j                  d|«      }|r3|j	                  «       \  }}||| }| j                   j                  |«       |S )Nrž   z\d+)r«   rÛ  rÕ   rÒ   rU  r©   )r1   rª   rÛ  rÒ   rß  rW  s         r4   rM  z"MTextParser.extract_int_expression  s]   € ØˆØ�|‰|× Ñ Ó"ˆÜ—‘˜ Ó&ˆÙØŸ™›‰JˆE�3Ø˜% �_ˆFØ�L‰L× Ñ  Ô%Øˆr6   c                ó  — | j                   j                  d|¬«      }|dk  r| j                   j                  «       }n| j                   j                  |«      }| j                   j	                  t        |«      dz   «       |S )zÈReturns the next expression from the current location until
        the terminating ";". The terminating semicolon is not included.
        Skips escaped "\;" semicolons if `escape` is True.

        r¹   r  r   rN   )r«   rÖ  rÛ  rÙ  r©   rÙ   )r1   rÕ  rØ  rI  s       r4   r  zMTextParser.extract_expression  si   € ð �|‰|× Ñ  ¨VÐ Ó4ˆØ�!Š8Ø—<‘<×$Ñ$Ó&‰Dà—<‘<×&Ñ& tÓ,ˆDà�‰×ÑœS ›Y¨™]Ô+Øˆr6   c           	     ó   ‡‡‡— dˆfd„}dˆˆfd„Šˆfd„Št        | j                  «       «      Š|j                  \  }}}}}‰j                  �r$‰j	                  «       }|dk(  r |«       }nù|dk(  r |«       }nì|dk(  r |«       }nß|dk(  rnÙ|dk(  r<‰j	                  «       }	t
        j	                  |	t        j                  «      } ‰«        n˜|d	k(  r“g }‰j                  r…‰j                  «       }
|
dk(  s|
d
k(  r*‰j                  «        |j                  |
 ‰«       z   «       n4 ‰«       }|r|j                  t        |«      «       n‰j                  «        ‰j                  rŒ…‰j                  r�Œ$t        ||||t        |«      «      |_        y )Nc                 ó4   •— d}  ‰«       }|rt        |«      } | S )Nr‹   )r   )r°  rI  Úparse_float_exprs     €r4   Úparse_floatz;MTextParser.parse_paragraph_properties.<locals>.parse_float+  s!   ø€ ØˆEÙ#Ó%ˆDÙÜ˜d›�ØˆLr6   c                 óÄ   •— d} ‰j                  «       }t        j                  t        |«      }|r0|j	                  «       \  }}||| } ‰j                  |«        ‰«        | S rR  )rÛ  rÕ   rÒ   rT  rU  r©   )rI  rÛ  rÒ   rß  rW  Úparagraph_scannerÚskip_commass        €€r4   r\  z@MTextParser.parse_paragraph_properties.<locals>.parse_float_expr2  s[   ø€ ØˆDØ$×)Ñ)Ó+ˆDÜ—H‘HœX tÓ,ˆEÙØ"ŸZ™Z›\‘
��sØ˜E #��Ø!×)Ñ)¨#Ô.Ù”ØˆKr6   c                 óx   •— ‰ j                  «       dk(  r&‰ j                  d«       ‰ j                  «       dk(  rŒ%y y )Nr   rN   )r¦   r©   )r_  s   €r4   r`  z;MTextParser.parse_paragraph_properties.<locals>.skip_commas=  s5   ø€ Ø#×(Ñ(Ó*¨cÒ1Ø!×)Ñ)¨!Ô,ð $×(Ñ(Ó*¨cÕ1r6   r.  r  r  rg   r/  rô   rÓ   r~   r5  )r¢   r  ré   r¥   r˜   ÚCHAR_TO_ALIGNr   r7  r¦   r©   r¿   r   r&  r+  )r1   rò  r]  r'  r(  r)  r*  r,  r  Ú
adjustmentr  Ú
float_exprr_  r\  r`  s               @@@r4   r8  z&MTextParser.parse_paragraph_properties*  sm  ú€ õ	ö		ô	-ô (¨×(?Ñ(?Ó(AÓBÐØ03·±Ñ-ˆ��e˜U IØ×(Ó(Ø#×'Ñ'Ó)ˆCØ�cŠzÙ$›‘Ø˜’Ù"“}‘Ø˜’Ù#›‘Ø˜’ØØ˜’Ø.×2Ñ2Ó4�
Ü%×)Ñ)¨*Ô6M×6UÑ6UÓV�Ù•Ø˜’Ø�	Ø'×0Ò0Ø-×2Ñ2Ó4�EØ ’| u°¢|Ø)×1Ñ1Ô3Ø!×(Ñ(¨Ñ1AÓ1CÑ)CÕDá%5Ó%7˜
Ù%Ø%×,Ñ,¬U°:Ó->Õ?ð .×5Ñ5Ô7ð (×0Ó0ð!  ×(Ô(ô: ,Ø�D˜% ¬¨iÓ(8ó
ˆ�r6   c                ó
  — ddl m} | j                  «       j                  d«      }|r\|d   rV|d   }d}d}|dd  D ]*  }|j	                  d«      rd}Œ|j	                  d	«      sŒ)d
}Œ,  |j
                  |||¬«      |_        y y y )Nr   r%   Ú|ÚRegulari�  rN   Úb1i¼  Úi1ÚItalic)Úfamilyr  Úweight)r–  r&   r  rÄ   Ú
startswithr›  rœ  )r1   rò  r&   ÚpartsrN  r  rl  Úparts           r4   r9  z!MTextParser.parse_font_propertiesd  s�   € Ý%à×'Ñ'Ó)×/Ñ/°Ó4ˆá�U˜1’XØ˜‘8ˆDØˆEØˆFð ˜a˜b›	�Ø—?‘? 4Ô(Ø ‘FØ—_‘_ TÕ*Ø$‘Eð	 "ð
 +˜EŸN™N°$¸eÈFÔSˆC�Mð ˆ5r6   c                óv   — | j                   j                  «       dk(  r| j                   j                  d«       y y )Nr¹   rN   )r«   r¦   r©   rD   s    r4   r=  z'MTextParser.consume_optional_terminatorv  s.   € Ø�<‰<×ÑÓ #Ò%Ø�L‰L× Ñ  Õ#ð &r6   rö  )rè   rz   rò  zOptional[MTextContext])r|   zIterator[MTextToken]r¹  r  )r  rz   r|   r}   )rò  r“  r~   rá  r5  )r„   r…   r†   r‡   r5   rý  rÿ  r  rü  r
  r  r1  r4  r5  r7  r?  r6  r2  r3  rF  rM  r  r8  r9  r=  rn   r6   r4   rã   rã   Ò  s”   „ ñð$ '+Ø %ð	FàðFð $óFóó)ó-ótól-Hó^.ó`+ó+ó+ó+óó+ó+ó+ô	óôó8
ótTó$$r6   rã   c                ó`   — d}d}| D ]  \  }}|dk(  r|}Œ|dk(  sŒ||z  }Œ t        ||z   «      S )Nrž   rN   r    )rÿ   )ÚtagsrÛ  rè   r­   r°  s        r4   Úload_mtext_contentrs  {  sH   € Ø€DØ€GÛ‰ˆˆeØ�1Š9Ø‰DØ�Q‹YØ�uÑ‰Gð	 ô
 # 7¨T¡>Ó2Ð2r6   c                óJ   — d| j                  dd«      j                  dd«      v S )zDReturns `True` if `text` contains any MTEXT inline formatting codes.r²   rû   rž   rD  rü   rþ   s    r4   Úhas_inline_formatting_codesru  †  s0   € ð �4—<‘<Øˆróç�gØˆróðð r6   c                ó8   — | dz  } d|z   | cxk  xr d|z
  k  S c S )uŒ  Returns ``True`` if the given text `angle` in degrees causes an upside
    down text in the :ref:`WCS`. The strict flip range is 90Â° < `angle` < 270Â°,
    the tolerance angle `tol` extends this range to: 90+tol < `angle` < 270-tol.
    The angle is normalized to [0, 360).

    Args:
        angle: text angle in degrees
        tol: tolerance range in which text flipping will be avoided

    ç     €v@g     €V@g     àp@rn   ©rV   Útols     r4   Úis_upside_down_text_anglerz  •  s+   € ð 
ˆU�N€EØ�#‰:˜Ö+ ¨¡Ñ+Ð+Ñ+Ð+r6   c                ó.   — t        | |«      r| dz  } | dz  S )a   Returns a readable (upright) text angle in the range `angle` <= 90+tol or
    `angle` >= 270-tol. The angle is normalized to [0, 360).

    Args:
        angle: text angle in degrees
        tol: tolerance range in which text flipping will be avoided

    g     €f@rw  )rz  rx  s     r4   Úupright_text_angler|  ¤  s!   € ô ! ¨Ô,Ø�‰ˆØ�5‰=Ðr6   c                ó   — | dz  |z  S )zµReturns the distance from baseline to baseline.

    Args:
        cap_height: cap height of the line
        line_spacing: line spacing factor as percentage of 3-on-5 spacing

    gyé&1¬ú?rn   )r�   Úline_spacings     r4   Úleadingr  ²  s   € ð ˜Ñ Ñ,Ð,r6   c                ó²   ‡ — dˆ fd„}t        ‰ j                   |«       ‰ j                  j                  dd«      ‰ j                  j	                  d«      ¬«      S )a\  Estimate the width and height of a single column
    :class:`~ezdxf.entities.MText` entity.

    This function is faster than the :func:`~ezdxf.tools.text_size.mtext_size`
    function, but the result is very inaccurate if inline codes are used or
    line wrapping at the column border is involved!

    Returns:
        Tuple[width, height]

    c                 ó4  •— ddl m}  ‰j                  j                  d«      }‰j                  }|rG|j
                  j                  ‰j                  j                  d«      «      }|�|j                  |«      S  | j                  t        j                  |¬«      S )Nr   r%   Úchar_heightr  )r�   )
r–  r&   r—   Úget_defaultr  r  r˜   Ú	make_fontr   ÚDEFAULT_TTF)r&   r�   r  r  Úmtexts       €r4   Ú
_make_fontz*estimate_mtext_extents.<locals>._make_fontÌ  su   ø€ Ý%à!ŸI™I×1Ñ1°-Ó@ˆ
Ø�i‰iˆÙØ—J‘J—N‘N 5§9¡9×#8Ñ#8¸Ó#AÓBˆEØÐ Ø—‘ zÓ2Ð2Øˆu�‰œu×0Ñ0¸ZÔHÐHr6   rE   r‹   Úline_spacing_factor)rè   r3   Úcolumn_widthrˆ  )r|   r{   )Úestimate_mtext_content_extentsr2   r—   r˜   rƒ  )r†  r‡  s   ` r4   Úestimate_mtext_extentsr‹  ¿  sI   ø€ õ	Iô *Ø—
‘
Ù‹\Ø—Y‘Y—]‘] 7¨CÓ0Ø!ŸI™I×1Ñ1Ð2GÓHô	ð r6   ç)\�Âõ(ð?c                ó   — | a y)z7Set the global safety factor for MTEXT size estimation.N©Ú_SAFETY_FACTOR)rV  s    r4   Úset_estimation_safety_factorr�  â  s	   € ð �Nr6   c                 ó   — da y)zbReset the global safety factor for MTEXT size estimation to the hard coded
    default value.
    rŒ  NrŽ  rn   r6   r4   Úreset_estimation_safety_factorr’  è  s	   € ð
 �Nr6   c                ó°  — d}d}|j                   j                  }|dkD  }t        | d¬«      }t        |«      r•d}	|D ]q  }
|j	                  |
«      }|dk(  r|
rt        |
«      |j                  «       z  }|r(|	t        j                  ||z  «      z  }	t        ||«      }n|	dz  }	t        ||«      }Œs t        ||«      |z
  }||	z  ||	dz
  z  z   }|t        z  |fS )ac  Estimate the width and height of the :class:`~ezdxf.entities.MText`
    content string. The result is very inaccurate if inline codes are used or
    line wrapping at the column border is involved!
    Column breaks ``\N`` will be ignored.

    Args:
        content: the :class:`~ezdxf.entities.MText` content string
        font: font abstraction based on :class:`ezdxf.tools.fonts.AbstractFont`
        column_width: :attr:`MText.dxf.width` or 0.0 for an unrestricted column
            width
        line_spacing_factor: :attr:`MText.dxf.line_spacing_factor`

    Returns:
        tuple[width, height]

    r‹   T)rÄ   r   rN   )rG   r�   rÊ   Úanyr-   rÙ   Úspace_widthrw   ÚceilÚminÚmaxr  r�  )rè   r3   r‰  rˆ  Ú	max_widthrI   r�   Úhas_column_widthr  Ú
line_countr  Ú
line_widthÚspacings                r4   rŠ  rŠ  ð  sö   € ð, €IØ€FØ×)Ñ)×4Ñ4€JØ)¨CÑ/ÐÜ'¨°tÔ<€Eä
ˆ5„zØˆ
ÛˆDØŸ™¨Ó.ˆJØ˜QŠ¡4ô ! ›Y¨×)9Ñ)9Ó);Ñ;�
ÙàœdŸi™i¨
°\Ñ(AÓBÑB�
Ü  ¨\Ó:‘
à˜a‘�
ô ˜I zÓ2‰Ið ô" ˜*Ð&9Ó:¸ZÑGˆØ˜jÑ(¨7°jÀ1±nÑ+EÑEˆà”~Ñ% vÐ-Ð-r6   c                ó@   — t        | t        «      rt        | «      d| S y)ziReturns a string with line breaks ``\n`` replaced by ``\P`` and the
    length limited to `max_len`.
    Nrž   )r8   rz   rÿ   )rÚ   Úmax_lens     r4   Úsafe_stringr   %  s#   € ô �!”SÔÜ& qÓ)¨(¨7Ð3Ð3Ør6   z0123456789.c                óÆ   ‡— dˆfd„}d| vr| S t        ‰«      Š| j                  d«      }|d   g}|dd D ]  }|j                   ||d«      «       Œ dj                  |«      S )zGScale all inline commands which define an absolute value by a `factor`.c                óâ   •— d}	 | |   t         v r|dz  }| |   t         v rŒ| |   dk(  r|› | › �S 	 	 t        | d | «      ‰z  }|d›}|› |› | |d  › �S # t        $ r Y Œ,w xY w# t        $ r d}Y Œ'w xY w)Nr   rN   rg   z.3grž   )ÚVALID_HEIGHT_CHARSr¾   r   re  )rÙ  ÚprefixrÝ  Únew_sizer°  rV  s        €r4   Ú_scale_leading_numberz:scale_mtext_inline_commands.<locals>._scale_leading_number4  sº   ø€ Øˆð	Ø˜‘-Ô#5Ñ5Ø˜‘
�ð ˜‘-Ô#5Ò5à�e‰} Ò#Ø ˜ & Ð*Ð*ð $ð	Ü˜V F U˜^Ó,¨vÑ5ˆHØ �nˆEð �(˜5˜' &¨¨ .Ð!1Ð2Ð2øô ò 	Ùð	ûô
 ò 	ØŠEð	ús'   …A ¡A ±A  Á	AÁAÁ A.Á-A.rR  r   rN   Nrž   )rÙ  rz   r¤  rz   r|   rz   )rH  rÄ   r¿   rÃ   )rè   rV  r¦  Ú	old_partsÚ	new_partsro  s    `    r4   Úscale_mtext_inline_commandsr©  1  sp   ø€ õ3ð$ �GÑØˆä�‹[€FØ—‘˜eÓ$€IØ% a™L˜>€IØ˜!˜"“ˆØ×ÑÑ.¨t°UÓ;Õ<ð ð �7‰7�9ÓÐr6   )rŒ   r   rT   r�   r|   r   )rW   r€   rU   r�   r|   r   )r›   zUnion[Text, MText]r|   ztuple[int, int])r2   rz   r|   rz   rá  )r2   rz   r|   úUnion[list[str], str])éú   )rÚ   rz   rÛ   r�   r|   ú	list[str])Fr'   )r2   rz   rç   r�   r|   rª  )u   â–¯)r2   rz   r  rz   r|   rz   )r¬   rz   r|   r€  )r2   rz   r  zOptional[float]r  zCallable[[str], float]r|   r¬  )r2   r#   r|   r€  )rÚ   rz   r|   rz   )rr  r$   r|   rz   )r2   rz   r|   r€  )g      @)rV   r   ry  r   r|   r€  )rV   r   ry  r   r|   r   )r+   )r�   r   r~  r   r|   r   )r†  r"   r|   r‚   )rV  r   r|   r}   r¹  )r‹   r+   )
rè   rz   r3   r{   r‰  r   rˆ  r   r|   r‚   )rÚ   zOptional[str]rŸ  r�   r|   rz   )rè   rz   rV  r   r|   rz   )dr‡   Ú
__future__r   Útypingr   r   r   r   r   r	   r
   r   ÚenumrÕ   rw   Úezdxf.lldxfr   r   Úezdxf.enumsr   r   r   r   r   r   Úezdxf.lldxf.constr   r   r   r   r   r   r   Ú
ezdxf.mathr   r   r   Úezdxf.colorsr   r   r    Úezdxf.entitiesr!   r"   r#   Úezdxf.lldxf.tagsr$   r–  r&   r�   r)   rb   rc   rœ   r¯   rÀ   rÊ   r¤   rß   rø   rÿ   r  r  r  r  r7  Ú	JUSTIFIEDÚDISTRIBUTEDr1  r0  ÚDIGITSr$  r&  r9  Ú	Exceptionr‘  r“  r¢   ÚIntEnumrâ   rð  ÚcompilerT  rS  rb  rã   rs  ru  rz  r|  r  r‹  r�  r�  r’  rŠ  r   Úsetr£  r©  rn   r6   r4   Ú<module>r¾     s²  ðñõ #÷	÷ 	ó 	ó Û 	Û ç (÷÷ ÷÷ ñ ÷ (Ñ 'ß .Ñ .ñ ß5Ñ5Ý%Ý!à€÷j/ñ j/óZó	ó.ó:ð<  Ð ôdK3ó\1ô ð, Øð7Ø
ð7ð ð7ð ó	7ót7ôQó0ð1Ø
ð1àð1ð +ð1ð ó	1óhð ×#Ñ# RØ× Ñ  #Ø×!Ñ! 3Ø×"Ñ" CØ×%Ñ% sØ×'Ñ'¨ð€ð 	€Ø	€óô=˜*ô =÷Ho&ñ o&ôd	�Yô 	÷j"ñ j"÷ZU&ñ U&ôp
�—‘ô 
÷ñ ð ˆ2�:‰:Ð<Ó=€ØˆR�Z‰ZÐDÓE€
ð 
!×	%Ñ	%Ø	 ×	&Ñ	&Ø	 ×	'Ñ	'Ø	 ×	*Ñ	*Ø	 ×	,Ñ	,ñ€÷f$ñ f$óR3óô,ôô
-óð@ €óóð Ø!$ð	2.Øð2.à
ð2.ð ð2.ð ð	2.ð
 ó2.ðj 2=ô ñ ˜Ó'Ð ôr6   