
    \
jb                       d Z ddlZddlZddlT ddlmZ ddlmZ ddlmZ ddl	m
Z
  eed          oej        Z ej        d	          Zd
 Z G d d          Z G d d          Z G d de          Z G d de          Z G d d          Z G d de          Z G d de          Z G d d          Z G d dej                  Z G d dej                  Z G d d ej                  Z G d! d"ej                  Z G d# d$ej                  Z G d% d&ej                  Z  G d' d(          Z! G d) d*e!          Z" G d+ d,e!ej#                  Z$e$%                    d-           dS ).a  Render simple text and formatted documents efficiently.

Three layout classes are provided:

:py:class:`~pyglet.text.layout.TextLayout`
    The entire document is laid out before it is rendered.  The layout will
    be grouped with other layouts in the same batch (allowing for efficient
    rendering of multiple layouts).

    Any change to the layout or document,
    and even querying some properties, will cause the entire document
    to be laid out again.

:py:class:`~pyglet.text.layout.ScrollableTextLayout`
    Based on :py:func:`~pyglet.text.layout.TextLayout`.

    A separate group is used for layout which crops the contents of the
    layout to the layout rectangle.  Additionally, the contents of the
    layout can be "scrolled" within that rectangle with the ``view_x`` and
    ``view_y`` properties.

:py:class:`~pyglet.text.layout.IncrementalTextLayout`
    Based on :py:class:`~pyglet.text.layout.ScrollableTextLayout`.

    When the layout or document are modified, only the affected regions
    are laid out again.  This permits efficient interactive editing and
    styling of text.

    Only the visible portion of the layout is actually rendered; as the
    viewport is scrolled additional sections are rendered and discarded as
    required.  This permits efficient viewing and editing of large documents.

    Additionally, this class provides methods for locating the position of a
    caret in the document, and for displaying interactive text selections.

All three layout classes can be used with either :py:class:`~pyglet.text.document.UnformattedDocument` or
:py:class:`~pyglet.text.document.FormattedDocument`, and can be either single-line or ``multiline``.  The
combinations of these options effectively provides 12 different text display
possibilities.

Style attributes
================

The following character style attribute names are recognised by the layout
classes.  Data types and units are as specified.

Where an attribute is marked "as a distance" the value is assumed to be
in pixels if given as an int or float, otherwise a string of the form
``"0u"`` is required, where ``0`` is the distance and ``u`` is the unit; one
of ``"px"`` (pixels), ``"pt"`` (points), ``"pc"`` (picas), ``"cm"``
(centimeters), ``"mm"`` (millimeters) or ``"in"`` (inches).  For example,
``"14pt"`` is the distance covering 14 points, which at the default DPI of 96
is 18 pixels.

``font_name``
    Font family name, as given to :py:func:`pyglet.font.load`.
``font_size``
    Font size, in points.
``bold``
    Boolean.
``italic``
    Boolean.
``underline``
    4-tuple of ints in range (0, 255) giving RGBA underline color, or None
    (default) for no underline.
``kerning``
    Additional space to insert between glyphs, as a distance.  Defaults to 0.
``baseline``
    Offset of glyph baseline from line baseline, as a distance.  Positive
    values give a superscript, negative values give a subscript.  Defaults to
    0.
``color``
    4-tuple of ints in range (0, 255) giving RGBA text color
``background_color``
    4-tuple of ints in range (0, 255) giving RGBA text background color; or
    ``None`` for no background fill.

The following paragraph style attribute names are recognised.  Note
that paragraph styles are handled no differently from character styles by the
document: it is the application's responsibility to set the style over an
entire paragraph, otherwise results are undefined.

``align``
    ``left`` (default), ``center`` or ``right``.
``indent``
    Additional horizontal space to insert before the first glyph of the
    first line of a paragraph, as a distance.
``leading``
    Additional space to insert between consecutive lines within a paragraph,
    as a distance.  Defaults to 0.
``line_spacing``
    Distance between consecutive baselines in a paragraph, as a distance.
    Defaults to ``None``, which automatically calculates the tightest line
    spacing for each line based on the font ascent and descent.
``margin_left``
    Left paragraph margin, as a distance.
``margin_right``
    Right paragraph margin, as a distance.
``margin_top``
    Margin above paragraph, as a distance.
``margin_bottom``
    Margin below paragraph, as a distance.  Adjacent margins do not collapse.
``tab_stops``
    List of horizontal tab stops, as distances, measured from the left edge of
    the text layout.  Defaults to the empty list.  When the tab stops
    are exhausted, they implicitly continue at 50 pixel intervals.
``wrap``
    ``char``, ``word``, True (default) or False.  The boundaries at which to
    wrap text to prevent it overflowing a line.  With ``char``, the line
    wraps anywhere in the text; with ``word`` or True, the line wraps at
    appropriate boundaries between words; with False the line does not wrap,
    and may overflow the layout width.  ``char`` and ``word`` styles are
    since pyglet 1.2.

Other attributes can be used to store additional style information within the
document; they will be ignored by the built-in text classes.

.. versionadded:: 1.1
    N)*)event)graphics)runlist)_grapheme_breakis_pyglet_doc_runz([-0-9.]+)([a-zA-Z]+)c                 j   t          | t                    r| S t          | t                    rt          |           S t                              |           }|sJ d| z              |sdS |                                \  }}t          |          }|dk    rt          |          S |dk    rt          ||z  dz            S |dk    rt          ||z  dz            S |dk    rt          ||z            S |d	k    rt          ||z  d
z            S |dk    rt          ||z  dz            S J d|z              )z[Parse a distance string and return corresponding distance in pixels as
    an integer.
    zCould not parse distance %sr   pxptg      R@pcg      @inmmgc6P(?cmg$d2?FzUnknown distance unit %s)
isinstanceintfloat_distance_rematchgroups)distancedpir   valueunits        L/DATA/AppData/hermes/venv/lib/python3.11/site-packages/pyglet/text/layout.py_parse_distancer      sQ    (C   	He	$	$ 8}}x((E::/(:::5 q,,..KE4%LLEt||5zz	53;%&&&	53;$%%%	53;	53;-...	53;,---704777u    c                   R    e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZd Zd Zd Zd ZdS )	_Lineleftr   FNc                 0    g | _         || _        g | _        d S N)vertex_listsstartboxesselfr#   s     r   __init__z_Line.__init__   s    



r   c                     d| j         z  S )Nz	_Line(%r))r$   r&   s    r   __repr__z_Line.__repr__   s    TZ''r   c                 
   | j                             |           | xj        |j        z  c_        t          | j        |j                  | _        t          | j        |j                  | _        | xj        |j        z  c_        d S r!   )	r$   appendlengthmaxascentmindescentwidthadvancer&   boxs     r   add_boxz_Line.add_box   sj    
#sz!$+sz224<55

ck!



r   c                     | j         D ]}|                                 g | _         | j        D ]}|                    |           d S r!   )r"   deleter$   )r&   layoutvertex_listr5   s       r   r8   z_Line.delete   sa    , 	! 	!K    : 	 	CJJv	 	r   )__name__
__module____qualname__alignmargin_leftmargin_rightr-   r/   r1   r2   paragraph_beginparagraph_endxyr'   r*   r6   r8    r   r   r   r      s        EKLFFGEOMAA  
( ( (" " "    r   r   c                       e Zd Zd ZdS )_LayoutContextc                     || _         |                    d          }t          j        ||f          | _        t          j        |                    d          d d          | _        d S )N	underlinebaselinec                 
    | d uS r!   rE   r   s    r   <lambda>z)_LayoutContext.__init__.<locals>.<lambda>       %t+ r   r   )colors_iterget_style_runsr   ZipRunIteratordecoration_iterFilteredRunIteratorbaseline_iter)r&   r9   documentrO   background_iterunderline_iters         r   r'   z_LayoutContext.__init__   si    &!00==&56WXX$8##J//++Q0 0r   N)r;   r<   r=   r'   rE   r   r   rG   rG      s#        0 0 0 0 0r   rG   c                   *     e Zd Z fdZd Zd Z xZS )_StaticLayoutContextc                     t                                          ||||           |j        | _        |j        | _        d S r!   )superr'   _vertex_listsr"   _boxesr$   )r&   r9   rU   rO   rV   	__class__s        r   r'   z_StaticLayoutContext.__init__   s9    ;HHH"0]


r   c                 :    | j                             |           d S r!   )r"   r,   r&   r:   s     r   add_listz_StaticLayoutContext.add_list  s      -----r   c                 :    | j                             |           d S r!   )r$   r,   r4   s     r   r6   z_StaticLayoutContext.add_box  s    
#r   )r;   r<   r=   r'   ra   r6   __classcell__r^   s   @r   rY   rY      sV        # # # # #
. . .      r   rY   c                       e Zd ZdZd Zd ZdS )_IncrementalLayoutContextNc                 D    | j         j                            |           d S r!   )liner"   r,   r`   s     r   ra   z"_IncrementalLayoutContext.add_list  s!    	%%k22222r   c                     d S r!   rE   r4   s     r   r6   z!_IncrementalLayoutContext.add_box      r   )r;   r<   r=   rh   ra   r6   rE   r   r   rf   rf     s7        D3 3 3    r   rf   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )_AbstractBoxNc                 >    || _         || _        || _        || _        d S r!   )r/   r1   r3   r-   )r&   r/   r1   r3   r-   s        r   r'   z_AbstractBox.__init__  s"    r   c                      t          d          NabstractNotImplementedErrorr&   r9   irC   rD   contexts         r   placez_AbstractBox.place      !*---r   c                      t          d          ro   rq   r&   r9   s     r   r8   z_AbstractBox.delete!  rw   r   c                      t          d          ro   rq   r&   rC   s     r   get_position_in_boxz _AbstractBox.get_position_in_box$  rw   r   c                      t          d          ro   rq   r&   positions     r   get_point_in_boxz_AbstractBox.get_point_in_box'  rw   r   )	r;   r<   r=   ownerr'   rv   r8   r|   r   rE   r   r   rl   rl     sd        E  . . .. . .. . .. . . . .r   rl   c                   <     e Zd Z fdZd Zd Zd Zd Zd Z xZ	S )	_GlyphBoxc                     t                                          |j        |j        |t	          |                     |sJ || _        || _        || _        || _        dS )ao  Create a run of glyphs sharing the same texture.

        :Parameters:
            `owner` : `pyglet.image.Texture`
                Texture of all glyphs in this run.
            `font` : `pyglet.font.base.Font`
                Font of all glyphs in this run.
            `glyphs` : list of (int, `pyglet.font.base.Glyph`)
                Pairs of ``(kern, glyph)``, where ``kern`` gives horizontal
                displacement of the glyph in pixels (typically 0).
            `advance` : int
                Width of glyph run; must correspond to the sum of advances
                and kerns in the glyph list.

        N)	r[   r'   r/   r1   lenr   fontglyphsr3   )r&   r   r   r   r3   r^   s        r   r'   z_GlyphBox.__init__,  sV      	dlGS[[IIIu
	r   c                    | j         sJ 	 |j        | j                 }n9# t          $ r, t	          | j        |j                  x}|j        | j        <   Y nw xY w| j        }g }g }	|}
|j                            |||z             D ]\  }}}|	                    |          }t          | j         ||z
  ||z
                     ||z
  k    sJ | j         ||z
  ||z
           D ]\  }}|
|z  }
|j        \  }}}}||
z  }||
z  }|||z   z  }|||z   z  }|                    t          t          ||||||||g                     |j        }|	                    |           |
|j        z  }
g }|j                            |||z             D ](\  }}}|d}|                    |||z
  dz  z             )|j                            |dz  t(          |d|fd|	fd|f          }|                    |           g }g }g }g }|| j        z   |z   }|| j        z   |z   }|}
|j                            |||z             D ]\  }}}|\  }} |
}!| j         ||z
  ||z
           D ]\  }}|!|j        |z   z  }!|5|                    |
||!||!||
|g           |                    |dz             | =|                    |
||z   dz
  |!||z   dz
  g           |                    | dz             |!}
|rQ|j                            t          |          dz  t(          |j        d|fd|f          }"|                    |"           |rS|j                            t          |          dz  t4          |j        d|fd|f          }#|                    |#           d S d S )Nr   r   r         zv2f/dynamiczt3f/dynamiczc4B/dynamic   )r   r   r   KeyErrorTextLayoutTextureGroupforeground_groupr-   rT   rangesr   r   verticesextendmapr   
tex_coordsr3   rO   batchaddGL_QUADSra   r1   r/   rR   background_groupGL_LINESforeground_decoration_group)$r&   r9   rt   rC   rD   ru   groupn_glyphsr   r   x1r#   endrJ   kernglyphv0v1v2v3tcolorscolorr:   background_verticesbackground_colorsunderline_verticesunderline_colorsy1y2
decorationbgrI   x2background_listunderline_lists$                                       r   rv   z_GlyphBox.placeC  s   {{	lM$*-EE 	l 	l 	l0FtzSYSj0k0kkEFM$*---	l ;
$+$9$@$@AL$Q$Q 	$ 	$ E3--h77Ht{519S1W#4566#+EEEE#{519S1W+<= 
$ 
$ed
!&BBbba(l"a(l"C"b"b"b"b)I J JKKK$!!!$$$em#
$ !(!4!;!;Aq8|!L!L 	7 	7E3}&MM%C%K1#456666l&&x!|Xu(5x'@(5z'B(5v'>@ @ 	%%% !(_x'&-&=&D&DQH&U&U 	 	"E3
&MB	B#{519S1W+<= + +eemd**~#**BBBB+KLLL!((a000$"))2q8|a/?Q\TUEU*VWWW ''	A666BB 	.$l..'((A-x' 34 12	4 4O
 _--- 	-#\--&''1,h2 23 01	3 3N
 ^,,,,,	- 	-s    3AAc                     d S r!   rE   ry   s     r   r8   z_GlyphBox.delete  rj   r   c                 X    d}| j         D ]\  }}|dk    r n|dz  }||j        |z   z  } |S Nr      r   r3   )r&   r   rC   r   r   s        r   r   z_GlyphBox.get_point_in_box  sK    ![ 	& 	&MT51}}MH%%AAr   c                 z    d}d}| j         D ].\  }}||z  }||j        dz  z   |k    r|c S |dz  }||j        z  }/|S )Nr   r   r   r   )r&   rC   r   last_glyph_xr   r   s         r   r|   z_GlyphBox.get_position_in_box  sg    ; 	* 	*KD%D Lemq00144MHEM)LLr   c                     d| j         z  S )Nz_GlyphBox(%r))r   r)   s    r   r*   z_GlyphBox.__repr__  s    ,,r   
r;   r<   r=   r'   rv   r8   r   r|   r*   rc   rd   s   @r   r   r   +  s            .R- R- R-h    	 	 	- - - - - - -r   r   c                   <     e Zd Z fdZd Zd Zd Zd Zd Z xZ	S )_InlineElementBoxc                     t                                          |j        |j        |j        d           || _        d| _        dS )z5Create a glyph run holding a single element.
        r   FN)r[   r'   r/   r1   r3   elementplaced)r&   r   r^   s     r   r'   z_InlineElementBox.__init__  s;     	'/1MMMr   c                 v    | j                             |||           d| _        |                    |            d S )NT)r   rv   r   r6   rs   s         r   rv   z_InlineElementBox.place  s;    61a(((r   c                 Z    | j         r#| j                            |           d| _         d S d S )NF)r   r   removery   s     r   r8   z_InlineElementBox.delete  s7    ; 	 L'''DKKK	  	 r   c                      |dk    rdS | j         S Nr   r3   r~   s     r   r   z"_InlineElementBox.get_point_in_box  s    q==1<r   c                 &    || j         dz  k     rdS dS )Nr   r   r   r   r{   s     r   r|   z%_InlineElementBox.get_position_in_box  s    t|q   11r   c                     d| j         z  S )Nz_InlineElementBox(%r))r   r)   s    r   r*   z_InlineElementBox.__repr__  s    &55r   r   rd   s   @r   r   r     s              
            6 6 6 6 6 6 6r   r   c                   2    e Zd Zd Zd Zd Zd Zd Zd ZdS )_InvalidRangec                 6    t           j        | _        d| _        d S r   )sysmaxsizer#   r   r)   s    r   r'   z_InvalidRange.__init__  s    [
r   c                     | j         |k    r| xj         |z  c_         | j        |k    r| xj        |z  c_        |                     |||z              d S r!   )r#   r   
invalidate)r&   r#   r-   s      r   insertz_InvalidRange.insert  sZ    :JJ& JJ8uHHHHuv~.....r   c                     | j         |k    r| xj         ||z
  z  c_         n| j         |k    r|| _         | j        |k    r| xj        ||z
  z  c_        d S | j        |k    r	|| _        d S d S r!   )r#   r   r&   r#   r   s      r   r8   z_InvalidRange.delete  s|    :JJ#+%JJJZ%DJ8c>>HHe#HHHHXDHHH r   c                 ~    ||k    rd S t          | j        |          | _        t          | j        |          | _        d S r!   )r0   r#   r.   r   r   s      r   r   z_InvalidRange.invalidate  s:    %<<FU++
tx%%r   c                 V    | j         | j        }}t          j        | _         d| _        ||fS r   )r#   r   r   r   r   s      r   validatez_InvalidRange.validate  s)    Zs[
czr   c                 "    | j         | j        k    S r!   )r   r#   r)   s    r   
is_invalidz_InvalidRange.is_invalid  s    x$*$$r   N)	r;   r<   r=   r'   r   r8   r   r   r   rE   r   r   r   r     sn          / / /  & & &  % % % % %r   r   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )TextLayoutGroupa&  Top-level rendering group for :py:func:`~pyglet.text.layout.TextLayout`.

    The blend function is set for glyph rendering (``GL_SRC_ALPHA`` /
    ``GL_ONE_MINUS_SRC_ALPHA``).  The group is shared by all :py:func:`~pyglet.text.layout.TextLayout`
    instances as it has no internal state.
    c                     t          t          t          z             t          t                     t          t          t                     d S r!   )glPushAttribGL_ENABLE_BITGL_CURRENT_BITglEnableGL_BLENDglBlendFuncGL_SRC_ALPHAGL_ONE_MINUS_SRC_ALPHAr)   s    r   	set_statezTextLayoutGroup.set_state  s:    ]^3444L"899999r   c                 "    t                       d S r!   )glPopAttribr)   s    r   unset_statezTextLayoutGroup.unset_state  s    r   c                 j    t          t          | j                  t          t          t
          f          S r!   )hashidparentr   r   r   r)   s    r   __hash__zTextLayoutGroup.__hash__  s"    R__h>TUVVVr   c                 :    | j         |j         u o| j        |j        u S r!   )r^   r   r&   others     r   __eq__zTextLayoutGroup.__eq__  s    ~0PT[EL5PPr   c                 0    | j         j        d| j        dS )N())r^   r;   r   r)   s    r   r*   zTextLayoutGroup.__repr__  s    >222DKKK@@r   N)	r;   r<   r=   __doc__r   r   r   r   r*   rE   r   r   r   r     st         : : :
  W W WQ Q QA A A A Ar   r   c                   B    e Zd ZdZdZdZdZdZdZdZ	d Z
d Zd Zd ZdS )ScrollableTextLayoutGroupa(  Top-level rendering group for :py:class:`~pyglet.text.layout.ScrollableTextLayout`.

    The group maintains internal state for setting the clipping planes and
    view transform for scrolling.  Because the group has internal state
    specific to the text layout, the group is never shared.
    r   c                 X   t          t          t          z  t          z             t	          t
                     t          t          t                     t	          t                     t          | j        | j        | j        | j                   t          | j         | j         d           d S r   )r   r   GL_TRANSFORM_BITr   r   r   r   r   r   GL_SCISSOR_TEST	glScissorrC   rD   r2   heightglTranslatefview_xview_yr)   s    r   r   z#ScrollableTextLayoutGroup.set_state-  s    ]%55FGGGL"8999!!!$&$&$*dk:::dk\DK<33333r   c                     t          | j        | j        d           t          t                     t                       d S r   )r   r   r   	glDisabler   r   r)   s    r   r   z%ScrollableTextLayoutGroup.unset_state8  s3    T[$+q111/"""r   c                 
    | |u S r!   rE   r   s     r   r   z ScrollableTextLayoutGroup.__eq__=      u}r   c                      t          |           S r!   r   r)   s    r   r   z"ScrollableTextLayoutGroup.__hash__@      $xxr   N)r;   r<   r=   r   rC   rD   r2   r   r   r   r   r   r   r   rE   r   r   r   r     sz          	
A	AEFFF	4 	4 	4  
      r   r   c                      e Zd ZdZdZdZdZdZdZdZ	dZ
dZd Zd Zed             Zej        d             Zed             Zej        d             Zed	             Zej        d
             Zed             Zej        d             Zed             Zej        d             Zed             Zej        d             Zd Zd ZdS )IncrementalTextLayoutGroupa)  Top-level rendering group for :py:class:`~pyglet.text.layout.IncrementalTextLayout`.

    The group maintains internal state for setting the clipping planes and
    view transform for scrolling.  Because the group has internal state
    specific to the text layout, the group is never shared.
    r   c                 d   t          t          t          z  t          z             t	          t
                     t          t          t                     t	          t                     t          | j        | j        | j        z
  | j        | j                   t          | j        | j        d           d S r   )r   r   r   r   r   r   r   r   r   r   r   _clip_x_clip_y_clip_height_clip_widthr   translate_xtranslate_yr)   s    r   r   z$IncrementalTextLayoutGroup.set_stateT  s    ]%55FGGGL"8999!!!$,t/@ @$BRTXTefffT%t'7;;;;;r   c                     t          | j         | j         d           t          t                     t                       d S r   )r   r  r  r   r   r   r)   s    r   r   z&IncrementalTextLayoutGroup.unset_state_  s;    d&&)9(91===/"""r   c                     | j         S r!   )r	  r)   s    r   topzIncrementalTextLayoutGroup.topd  
    |r   c                 <    || _         | j         | j        z
  | _        dS )zuTop edge of the text layout (measured from the
        bottom of the graphics viewport).

        :type: int
        N)r	  _view_yr  )r&   r  s     r   r  zIncrementalTextLayoutGroup.toph  s"     <$,6r   c                     | j         S r!   )r  r)   s    r   r   zIncrementalTextLayoutGroup.leftr  r  r   c                 <    || _         | j         | j        z
  | _        dS )z:Left edge of the text layout.

        :type: int
        N)r  _view_xr  )r&   r   s     r   r   zIncrementalTextLayoutGroup.leftv  s"     <$,6r   c                     | j         S r!   r  r)   s    r   r2   z IncrementalTextLayoutGroup.width  s    r   c                     || _         dS )z6Width of the text layout.

        :type: int
        Nr  r&   r2   s     r   r2   z IncrementalTextLayoutGroup.width  s     !r   c                     | j         S r!   r
  r)   s    r   r   z!IncrementalTextLayoutGroup.height  s      r   c                     || _         dS )z7Height of the text layout.

        :type: int
        Nr  r&   r   s     r   r   z!IncrementalTextLayoutGroup.height  s     #r   c                     | j         S r!   )r  r)   s    r   r   z!IncrementalTextLayoutGroup.view_x  r  r   c                 <    || _         | j        | j         z
  | _        dS )z6Horizontal scroll offset.

        :type: int
        N)r  r  r  r&   r   s     r   r   z!IncrementalTextLayoutGroup.view_x  "     <$,6r   c                     | j         S r!   )r  r)   s    r   r   z!IncrementalTextLayoutGroup.view_y  r  r   c                 <    || _         | j        | j         z
  | _        dS )z4Vertical scroll offset.

        :type: int
        N)r  r	  r  r&   r   s     r   r   z!IncrementalTextLayoutGroup.view_y  r"  r   c                 
    | |u S r!   rE   r   s     r   r   z!IncrementalTextLayoutGroup.__eq__  r  r   c                      t          |           S r!   r  r)   s    r   r   z#IncrementalTextLayoutGroup.__hash__  r  r   N)r;   r<   r=   r   r  r	  r  r
  r  r  r  r  r   r   propertyr  setterr   r2   r   r   r   r   r   rE   r   r   r  r  D  s         GGKLGGKK	< 	< 	<  
   X 	Z7 7 Z7   X 
[7 7 [7     X  \! ! \! ! ! X! ]# # ]#   X ]7 7 ]7   X ]7 7 ]7      r   r  c                       e Zd ZdZd ZdS )TextLayoutForegroundGroupztRendering group for foreground elements (glyphs) in all text layouts.

    The group enables ``GL_TEXTURE_2D``.
    c                 .    t          t                     d S r!   )r   GL_TEXTURE_2Dr)   s    r   r   z#TextLayoutForegroundGroup.set_state  s    r   Nr;   r<   r=   r   r   rE   r   r   r+  r+    s-         
         r   r+  c                       e Zd ZdZd ZdS )#TextLayoutForegroundDecorationGroupzRendering group for decorative elements (e.g., glyph underlines) in all
    text layouts.

    The group disables ``GL_TEXTURE_2D``.
    c                 .    t          t                     d S r!   )r   r-  r)   s    r   r   z-TextLayoutForegroundDecorationGroup.set_state  s    -     r   Nr.  rE   r   r   r0  r0    s-         ! ! ! ! !r   r0  c                   :     e Zd ZdZ fdZd Zd Zd Zd Z xZ	S )r   zRendering group for a glyph texture in all text layouts.

    The group binds its texture to ``GL_TEXTURE_2D``.  The group is shared
    between all other text layout uses of the same texture.
    c                 |    |j         t          k    sJ t                                          |           || _        d S r!   )targetr-  r[   r'   texture)r&   r5  r   r^   s      r   r'   zTextLayoutTextureGroup.__init__  s9    ~....   r   c                 D    t          t          | j        j                   d S r!   )glBindTexturer-  r5  r   r)   s    r   r   z TextLayoutTextureGroup.set_state  s    mT\_55555r   c                 B    t          | j        j        | j        f          S r!   )r   r5  r   r   r)   s    r   r   zTextLayoutTextureGroup.__hash__  s    T\_dk2333r   c                 r    | j         |j         u o)| j        j        |j        j        k    o| j        |j        k    S r!   )r^   r5  r   r   r   s     r   r   zTextLayoutTextureGroup.__eq__  s:    %/1 ,5=#33,u|+	-r   c                 D    d| j         j        | j        j        | j        fz  S )Nz
%s(%d, %r))r^   r;   r5  r   r   r)   s    r   r*   zTextLayoutTextureGroup.__repr__  s    t~6UUUr   )
r;   r<   r=   r   r'   r   r   r   r*   rc   rd   s   @r   r   r     s             6 6 64 4 4- - -
V V V V V V Vr   r   c                      e Zd ZdZdZdZdZ e            Z e	j
        de          Z ede          Z ede          ZdZdZdZdZdZdZdZd	Zd
ZdZdZdZ	 	 	 dBdZed             Zed             Zej         d             Zed             Z!e!j         d             Z!ed             Z"e"j         d             Z"d Z#ed             Z$e$j         d             Z$d Z%ed             Z&e&j         d             Z&d Z'ed             Z(e(j         d             Z(ed             Z)e)j         d             Z)ed             Z*e*j         d              Z*ed!             Z+e+j         d"             Z+ed#             Z,e,j         d$             Z,ed%             Z-e-j         d&             Z-ed'             Z.e.j         d(             Z.d) Z/d* Z0d+ Z1d, Z2d- Z3d. Z4d/ Z5d0 Z6d1 Z7d2 Z8d3 Z9d4 Z:d5 Z;d6 Z<d7 Z=d8 Z>d9 Z?d: Z@d; ZAd< ZBd= ZCd> ZDd? ZEd@ ZFdA ZGdS )C
TextLayouta  Lay out and display documents.

    This class is intended for displaying documents that do not change
    regularly -- any change will cost some time to lay out the complete
    document again and regenerate all vertex lists.

    The benefit of this class is that texture state is shared between
    all layouts of this class.  The time to draw one :py:func:`~pyglet.text.layout.TextLayout` may be
    roughly the same as the time to draw one :py:class:`~pyglet.text.layout.IncrementalTextLayout`; but
    drawing ten :py:func:`~pyglet.text.layout.TextLayout` objects in one batch is much faster than drawing
    ten incremental or scrollable text layouts.

    :py:func:`~pyglet.text.Label` and :py:func:`~pyglet.text.HTMLLabel` provide a convenient interface to this class.

    :Ivariables:
        `content_width` : int
            Calculated width of the text in the layout.  This may overflow
            the desired width if word-wrapping failed.
        `content_height` : int
            Calculated height of the text in the layout.
        `top_group` : `~pyglet.graphics.Group`
            Top-level rendering group.
        `background_group` : `~pyglet.graphics.Group`
            Rendering group for background color.
        `foreground_group` : `~pyglet.graphics.Group`
            Rendering group for glyphs.
        `foreground_decoration_group` : `~pyglet.graphics.Group`
            Rendering group for glyph underlines.

    NrE   r   r   r   TFr   bottomr  c	                 ,   d| _         d| _        i | _        |                     |           |t	          j                    }d| _        || _        || _        ||| _	        |r|| _
        || _        |                                  |d}|| _        || _        dS )aB  Create a text layout.

        :Parameters:
            `document` : `AbstractDocument`
                Document to display.
            `width` : int
                Width of the layout in pixels, or None
            `height` : int
                Height of the layout in pixels, or None
            `multiline` : bool
                If False, newline and paragraph characters are ignored, and
                text is not word-wrapped.
                If True, text is wrapped only if the `wrap_lines` is True.
            `dpi` : float
                Font resolution; defaults to 96.
            `batch` : `~pyglet.graphics.Batch`
                Optional graphics batch to add this layout to.
            `group` : `~pyglet.graphics.Group`
                Optional rendering group to parent all groups this text layout
                uses.  Note that layouts with different
                rendered simultaneously in a batch.
            `wrap_lines` : bool
                If True and `multiline` is True, the text is word-wrapped using
                the specified width.

        r   NT`   )content_widthcontent_heightr   _init_groupsr   Batch
_own_batch_batch_width_height
_multiline_wrap_lines_flag_wrap_lines_invariant_dpirU   )	r&   rU   r2   r   	multiliner   r   r   
wrap_liness	            r   r'   zTextLayout.__init__&  s    : %   =N$$E"DO!DL 	('DO *""$$$;C	 r   c                     | j         S )z;Get DPI used by this layout.

        :type: float
        )rK  r)   s    r   r   zTextLayout.dpi\  s     yr   c                     | j         S )a  Document to display.

         For :py:class:`~pyglet.text.layout.IncrementalTextLayout` it is
         far more efficient to modify a document in-place than to replace
         the document instance on the layout.

         :type: `AbstractDocument`
         )	_documentr)   s    r   rU   zTextLayout.documentd  s     ~r   c                     | j         r.| j                             |            |                                  |                    |            || _         |                                  d S r!   )rP  remove_handlers_uninit_documentpush_handlers_init_document)r&   rU   s     r   rU   zTextLayout.documentp  sg    > 	$N**4000!!###t$$$!r   c                     | j         S )zThe Batch that this Layout is assigned to.

        If no Batch is assigned, an internal Batch is 
        created and used.

        :type: :py:class:`~pyglet.graphics.Batch`
        
        )rE  r)   s    r   r   zTextLayout.batchy  s     {r   c                     | j         |k    rd S |5t          j                    | _         d| _        |                                  d S |$|| _         d| _        |                                  d S d S )NTF)rE  r   rC  rD  _update)r&   r   s     r   r   zTextLayout.batch  sm    ;%F=".**DK"DOLLNNNNNDK#DOLLNNNNN r   c                     | j         S )z~X coordinate of the layout.

        See also :py:attr:`~pyglet.text.layout.TextLayout.anchor_x`.

        :type: int
        _xr)   s    r   rC   zTextLayout.x       wr   c                 0    |                      |           d S r!   )_set_xr{   s     r   rC   zTextLayout.x      Ar   c                     | j         r|| _        |                                  d S || j        z
  | j        D ]:}|j        d d          }fd|d d d         D             |d d d<   ||j        d d <   ;|| _        d S )Nc                     g | ]}|z   S rE   rE   .0rC   dxs     r   
<listcomp>z%TextLayout._set_x.<locals>.<listcomp>       ? ? ?AR ? ? ?r   r   )r]   r[  rX  r\   r   )r&   rC   r:   r   rd  s       @r   r^  zTextLayout._set_x  s    ; 		DGLLNNNNNTWB#1 3 3&/2 ? ? ? ?##A# ? ? ?1*2$QQQ''DGGGr   c                     | j         S )zVY coordinate of the layout.

        See also `anchor_y`.

        :type: int
        _yr)   s    r   rD   zTextLayout.y  r\  r   c                 0    |                      |           d S r!   )_set_yr&   rD   s     r   rD   zTextLayout.y  r_  r   c                     | j         r|| _        |                                  d S || j        z
  | j        D ]:}|j        d d          }fd|dd d         D             |dd d<   ||j        d d <   ;|| _        d S )Nc                     g | ]}|z   S rE   rE   rc  rD   dys     r   re  z%TextLayout._set_y.<locals>.<listcomp>      !A!A!AQ!b&!A!A!Ar   r   r   )r]   ri  rX  r\   r   )r&   rD   r:   r   rp  s       @r   rk  zTextLayout._set_y  s    ; 		DGLLNNNNNTWB#1 3 3&/2!A!A!A!A(14a4.!A!A!AA*2$QQQ''DGGGr   c                     | j         | j        fS )zThe (X, Y) coordinates of the layout, as a tuple.

        See also :py:attr:`~pyglet.text.layout.TextLayout.anchor_x`,
        and :py:attr:`~pyglet.text.layout.TextLayout.anchor_y`.

        :type: (int, int)
        r[  ri  r)   s    r   r   zTextLayout.position  s     wr   c                      | j         |  d S r!   )updater~   s     r   r   zTextLayout.position  s    Xr   c                 b   | j         r$|| _        || _        |                                  dS || j        z
  || j        z
  | j        D ]W}|j        dd         }fd|ddd         D             |ddd<   fd|ddd         D             |ddd<   ||j        dd<   X|| _        || _        dS )zChange both X and Y positions of the layout at once for faster performance.

        :Parameters:
            `x` : int
                X coordinate of the layout.
            `y` : int
                Y coordinate of the layout.
        Nc                     g | ]}|z   S rE   rE   rb  s     r   re  z%TextLayout.update.<locals>.<listcomp>  rf  r   r   c                     g | ]}|z   S rE   rE   ro  s     r   re  z%TextLayout.update.<locals>.<listcomp>  rq  r   r   )r]   r[  ri  rX  r\   r   )r&   rC   rD   r:   r   rd  rp  s        @@r   ru  zTextLayout.update  s     ; 	DGDGLLNNNNNTWBTWB#1 3 3&/2 ? ? ? ?##A# ? ? ?1!A!A!A!A(14a4.!A!A!AA*2$QQQ''DGDGGGr   c                     | j         S )z?True if the layout will be drawn.

        :type: bool
        )_visibler)   s    r   visiblezTextLayout.visible  s     }r   c                     || j         k    r5|| _         |r|                                  d S |                                  d S d S r!   )rz  rX  r8   )r&   r   s     r   r{  zTextLayout.visible  sH    DM!!!DM  "!r   c                     | j         S )zWidth of the layout.

        This property has no effect if `multiline` is False or `wrap_lines` is False.

        :type: int
        rF  r)   s    r   r2   zTextLayout.width   s     {r   c                 d    || _         |                                  |                                  d S r!   )rF  rJ  rX  r  s     r   r2   zTextLayout.width
  s,    ""$$$r   c                     | j         S )z2Height of the layout.

        :type: int
        rG  r)   s    r   r   zTextLayout.height  s     |r   c                 <    || _         |                                  d S r!   )rG  rX  r  s     r   r   zTextLayout.height  s    r   c                     | j         S )a   Set if multiline layout is enabled.

        If multiline is False, newline and paragraph characters are ignored and
        text is not word-wrapped.
        If True, the text is word-wrapped only if the `wrap_lines` is True.

        :type: bool
        rH  r)   s    r   rL  zTextLayout.multiline  s     r   c                 d    || _         |                                  |                                  d S r!   )rH  rJ  rX  r&   rL  s     r   rL  zTextLayout.multiline)  s,    #""$$$r   c                     | j         S )a  Horizontal anchor alignment.

        This property determines the meaning of the `x` coordinate.
        It is one of the enumerants:

        ``"left"`` (default)
            The X coordinate gives the position of the left edge of the layout.
        ``"center"``
            The X coordinate gives the position of the center of the layout.
        ``"right"``
            The X coordinate gives the position of the right edge of the layout.

        For the purposes of calculating the position resulting from this
        alignment, the width of the layout is taken to be `width` if `multiline`
        is True and `wrap_lines` is True, otherwise `content_width`.

        :type: str
        	_anchor_xr)   s    r   anchor_xzTextLayout.anchor_x/  s    ( ~r   c                 <    || _         |                                  d S r!   )r  rX  r&   r  s     r   r  zTextLayout.anchor_xE      !r   c                     | j         S )aA  Vertical anchor alignment.

        This property determines the meaning of the `y` coordinate.
        It is one of the enumerants:

        ``"top"``
            The Y coordinate gives the position of the top edge of the layout.
        ``"center"``
            The Y coordinate gives the position of the center of the layout.
        ``"baseline"``
            The Y coordinate gives the position of the baseline of the first
            line of text in the layout.
        ``"bottom"`` (default)
            The Y coordinate gives the position of the bottom edge of the layout.

        For the purposes of calculating the position resulting from this
        alignment, the height of the layout is taken to be the smaller of
        `height` and `content_height`.

        See also `content_valign`.

        :type: str
        	_anchor_yr)   s    r   anchor_yzTextLayout.anchor_yJ  s    2 ~r   c                 <    || _         |                                  d S r!   )r  rX  r&   r  s     r   r  zTextLayout.anchor_ye  r  r   c                     | j         S )a  Vertical alignment of content within larger layout box.

        This property determines how content is positioned within the layout
        box when ``content_height`` is less than ``height``.  It is one
        of the enumerants:

        ``top`` (default)
            Content is aligned to the top of the layout box.
        ``center``
            Content is centered vertically within the layout box.
        ``bottom``
            Content is aligned to the bottom of the layout box.

        This property has no effect when ``content_height`` is greater
        than ``height`` (in which case the content is aligned to the top) or when
        ``height`` is ``None`` (in which case there is no vertical layout box
        dimension).

        :type: str
        )_content_valignr)   s    r   content_valignzTextLayout.content_valignj  s    , ##r   c                 <    || _         |                                  d S r!   )r  rX  )r&   r  s     r   r  zTextLayout.content_valign  s    -r   c                 `    | j         o| j        | _        | j        r| j        sJ d            d S d S )NzaWhen the parameters 'multiline' and 'wrap_lines' are True,the parameter 'width' must be a number.)rH  rI  _wrap_linesrF  r)   s    r   rJ  z TextLayout._wrap_lines_invariant  sS    ?Dt/D# 	6t{ 	6 	66	6 	62 	6 	6 	6 	6r   c                 4    |d S t          || j                  S r!   )r   rK  )r&   r   s     r   r   zTextLayout._parse_distance  s    4x333r   c                     d| _         dS )a  Indicate that a number of changes to the layout or document
        are about to occur.

        Changes to the layout or document between calls to `begin_update` and
        `end_update` do not trigger any costly relayout of text.  Relayout of
        all changes is performed when `end_update` is called.

        Note that between the `begin_update` and `end_update` calls, values
        such as `content_width` and `content_height` are undefined (i.e., they
        may or may not be updated to reflect the latest changes).
        FN)_update_enabledr)   s    r   begin_updatezTextLayout.begin_update  s      %r   c                 <    d| _         |                                  dS )zZPerform pending layout changes since `begin_update`.

        See `begin_update`.
        TN)r  rX  r)   s    r   
end_updatezTextLayout.end_update  s    
  $r   c                     | j         D ]}|                                 g | _         | j        D ]}|                    |            dS )z+Remove this layout from its batch.
        N)r\   r8   r]   )r&   r:   r5   s      r   r8   zTextLayout.delete  sc      - 	! 	!K    ; 	 	CJJt	 	r   c                     | j         r| j                                         dS | j                            | j                   dS )zDraw this text layout.

        Note that this method performs very badly if a batch was supplied to
        the constructor.  If you add this layout to a batch, you should
        ideally use only the batch's draw method.
        N)rD  rE  drawdraw_subsetr\   r)   s    r   r  zTextLayout.draw  sG     ? 	8KK##D$677777r   c                     |rit          |          | _        t          j        d| j                  | _        t          d| j                  | _        t          d| j                  | _        d S d S Nr   r   r   )	r   	top_groupr   OrderedGroupr   r+  r   r0  r   r&   r   s     r   rB  zTextLayout._init_groups  sn     	f,U33DN$,$9!T^$L$LD!$=a$P$PD!/RSTVZVd/e/eD,,,		f 	fr   c                 T   t          | j        j                  }|                                 }t	          j        |d           }|                     ||d|           d |                     ||d|          D             }d| _        | 	                    |dt          |                     |S )Nr   c                     g | ]}|S rE   rE   )rc  rh   s     r   re  z)TextLayout._get_lines.<locals>.<listcomp>  s    UUU$UUUr   )
r   rP  text_get_glyphsr   RunList_get_owner_runs_flow_glyphsr@  _flow_lines)r&   len_textr   
owner_runsliness        r   
_get_lineszTextLayout._get_lines  s    t~*++!!##_Xt44
ZH===UU$"3"3FJ8"T"TUUU3u::...r   c                    | j         sd S | j        D ]}|                                 | j        D ]}|                    |            g | _        g | _        | j                                         | j        r| j        j        sd S |                                 }| j        	                    d          }| j        	                    d          }| j
        rdx}}n)|                                 }|                     |          }t          | | j        ||          }|D ]5}	|                     ||	j        z   ||	j        z   |	j        |	j        |           6d S )Nr   background_colorr   )r  r\   r8   r]   r   clearrP  r  r  rP   _origin_layout	_get_left_get_toprY   _create_vertex_listsrC   rD   r#   r$   )
r&   _vertex_listr5   r  rO   rV   r   r  ru   rh   s
             r   rX  zTextLayout._update  so   # 	F . 	" 	"L!!!!; 	 	CJJt~ 	T^%8 	F!!n33G<<.778JKK 	'ND33>>##D--&&C&tT^[/ZZ 	d 	dD%%dTVmS46\4:tz[bcccc	d 	dr   c                 T   | j                             d          }g }|                    d|j                  D ](\  }}}|d}|                    |||z
  dz  z             )d}| j        D ]=}|||t          |j                  z            |_        |t          |j                  z  }>d S )Nr   r   r   r   )rP  rP   r   r   r   r\   r   r   )r&   rO   r   r#   r   r   r  s          r   _update_colorzTextLayout._update_color  s    n33G<<!,!3!3A{!G!G 	7 	7E3}&MM%C%K1#456666 . 	. 	.L"(uS9L5M5M/M)M"NLS,---EE	. 	.r   c                     | j         r| j        r| j        n| j        }n| j        }| j        dk    r| j        S | j        dk    r| j        |dz  z
  S | j        dk    r
| j        |z
  S J d            )Nr   centerr   rightFz7`anchor_x` must be either "left", "center", or "right".)rH  r  rF  r@  r  r[  r  s     r   r  zTextLayout._get_left  s    ? 	'#'#3KDKK9KEE&E>V##7N^x''7UaZ''^w&&7U?"SSSS5r   c                 t   | j         
| j        }d}nt| j         }| j        dk    rd}n_| j        dk    rt          d| j         | j        z
            }n6| j        dk    r!t          d| j         | j        z
            dz  }n
J d            | j        dk    r
| j        |z
  S | j        dk    r| j        |d         j        z   |z
  S | j        dk    r| j        |z   |z
  S | j        dk    rOt          |          d	k    r,| j         %|d         }| j        |j        dz  z   |j        d
z  z
  S | j        |dz  z   |z
  S J d            )Nr   r  r=  r  r   Fz=`content_valign` must be either "top", "bottom", or "center".rJ   r   r   C`anchor_y` must be either "top", "bottom", "center", or "baseline".)	rG  rA  r  r.   r  ri  r/   r   r1   )r&   r  r   offsetrh   s        r   r  zTextLayout._get_top
  sh   <(FFF\F#u,,%11Qt/B BCC%11Qt/B BCCqH]]]]u>U""7V##^z))7U1X_,v55^x''7V#f,,^x''5zzQ4<#7Qxw!11DLA4EEEw1,v55____5r   c                     | j         p| j        }| j        dk    r
| j        |z
  S | j        dk    r| j        S | j        dk    r| j        |dz  z
  S | j        dk    r| j        |z
  |d         j        z   S J d            )	Nr  r=  r  r   rJ   r   Fr  )rG  rA  r  ri  r/   )r&   r  r   s      r   _get_bottomzTextLayout._get_bottom)  s    4!4>U""7V##^x''7N^x''7Vq[((^z))7V#eAho55____5r   c                 .    |                                   d S r!   )rX  r)   s    r   rU  zTextLayout._init_document7  s    r   c                     d S r!   rE   r)   s    r   rS  zTextLayout._uninit_document:  rj   r   c                     | j         r|                                  dS | j        j        r|                                  dS dS )zEvent handler for `AbstractDocument.on_insert_text`.

        The event handler is bound by the text layout; there is no need for
        applications to interact with this method.
        N)rz  rU  rU   r  r  )r&   r#   r  s      r   on_insert_textzTextLayout.on_insert_text=  sS     = 	"!!!!!}! "!!!!!" "r   c                 @    | j         r|                                  dS dS )zEvent handler for `AbstractDocument.on_delete_text`.

        The event handler is bound by the text layout; there is no need for
        applications to interact with this method.
        N)rz  rU  r   s      r   on_delete_textzTextLayout.on_delete_textJ  s0     = 	"!!!!!	" 	"r   c                     t          |          dk    r,d|                                v r|                                  dS |                                  dS )zEvent handler for `AbstractDocument.on_style_text`.

        The event handler is bound by the text layout; there is no need for
        applications to interact with this method.
        r   r   N)r   keysr  rU  r&   r#   r   
attributess       r   on_style_textzTextLayout.on_style_textS  sY     z??aGz/@/@$@$@     !!!!!r   c                    g }t          j        | j                            | j                  | j                                        f          }| j        j        }|                    dt          |                    D ]^\  }}\  }}|r#|	                    t          |                     .|                    |                    |||                              _|S )Nr   r   )r   rQ   rP  get_font_runsrK  get_element_runsr  r   r   r,   r   r   
get_glyphs)r&   r   runsr  r#   r   r   r   s           r   r  zTextLayout._get_glyphs^  s    %N((TY(77N++--'/ 0 0 ~"+/;;q#d))+D+D 	@ 	@'E3w @/889999dood59o>>????r   c                     ||         j         }|}t          |||                   D ]6\  }}||j         k    r&|                    |||z   |           |j         }||z   }7|                    |||           d S r!   )r   	enumerateset_run)	r&   r  r   r#   r   r   	run_startrt   r   s	            r   r  zTextLayout._get_owner_runsk  s    u#	!&s"344 	& 	&HAu##""9a%i???I	9c511111r   c              #      K   | j         s!|                     ||||          D ]}|V  d S |                     ||||          D ]}|V  d S r!   )rH  _flow_glyphs_single_line_flow_glyphs_wrap)r&   r   r  r#   r   rh   s         r   r  zTextLayout._flow_glyphsv  s       	55fj6;SB B  



  ..vz5#NN  



 r   c           
   #   
  K   |                                                     ||          }| j                            | j                  }t          j        | j                            d          d d          }| j        -t          j	        t          | j        j                  d          }n/t          j        | j                            d          d d	          }t          j        | j                            d
          d d          }	t          j        | j                            d          d d          }
t          j        | j                            d          d d          }t          j        | j                            d          d d          }t          j        | j                            d          d g           }t          |          }||         |_        |                     |	|                   |_        |                     |
|                   |_        |dk    s| j        j        |dz
           dv r0d	|_        |xj        |                     ||                   z  c_        ||         }| j        r| j        |j        z
  |j        z
  }d}g }d}d}d}|D ]~\  }}}||         }g }d}g }d}d	}|}t)          | j        j        ||         |||                   D ]\  }}|rd}d}n|                     ||                   }|dk    r|dv r|D ]} |                    |            g }d}|dk    rg||         D ]'}!|                     |!          }!|!||j        z   k    r n(d}"||j        z   |"z  dz   |"z  }!t-          |!|z
  |j        z
  |j        z
            }|                    ||f           |                    |           |||j        z   |z   z  }||j        |z   z  }g }d}||j        |z   z  }|dz  }|}# |dv }$|dk    p|$}%|r| j        r||z   |j        z   |k    s|%r|%s|dk    rU|D ]} |                    |            g }d}|                    |           ||z  }g }d}|xj        dz  c_        |}#|%r|#dz  }#|r)|                    t7          ||||                     g }d}|%r|j        s|j        |_        |j        |_        |j        s|%r|xj        |z  c_        |$rd	|_         |V  	 t          |#          }||#         |_        |                     |	|#                   |_        |                     |
|#                   |_        n# tB          $ r Y   dS w xY w|$rd	|_        |rEtE          |d          r5|j#        r.|d         j#        d         \  }&}'d|'f|d         j#        d<   ||&z  }n|r|d         \  }&}'d|'f|d<   ||&z  }nd	}||z   }| j        r| j        |j        z
  |j        z
  }tI          |tJ                    r*|                    |           ||j        z  }||j        z  }n|$rP||#         }|xj        |                     ||#                   z  c_        | j        r| j        |j        z
  |j        z
  }n3|%s1|                    ||f           ||j        |z   z  }||j        |z   z  }|dz  }d}|r%|                    t7          ||||                     |r*|                    t7          ||||                     ||z  }|D ]} |                    |            |j        s;|!| j        &                    d| j                  }|j        |_        |j        |_        |V  dS )zWord-wrap styled text into lines of fixed width.

        Fits `glyphs` in range `start` to `end` into `_Line` s which are
        then yielded.
        r  r>   c                 
    | dv S N)r   r  r  rE   rL   s    r   rM   z.TextLayout._flow_glyphs_wrap.<locals>.<lambda>  s    %#>> r   r   NFwrapc                 
    | dv S )N)TFcharwordrE   rL   s    r   rM   z.TextLayout._flow_glyphs_wrap.<locals>.<lambda>  s    e'DD r   Tr?   c                 
    | d uS r!   rE   rL   s    r   rM   z.TextLayout._flow_glyphs_wrap.<locals>.<lambda>  rN   r   r   r@   c                 
    | d uS r!   rE   rL   s    r   rM   z.TextLayout._flow_glyphs_wrap.<locals>.<lambda>  rN   r   indentc                 
    | d uS r!   rE   rL   s    r   rM   z.TextLayout._flow_glyphs_wrap.<locals>.<lambda>  rN   r   kerningc                 
    | d uS r!   rE   rL   s    r   rM   z.TextLayout._flow_glyphs_wrap.<locals>.<lambda>  rN   r   	tab_stopsc                 
    | d uS r!   rE   rL   s    r   rM   z.TextLayout._flow_glyphs_wrap.<locals>.<lambda>  rN   r   r   u   
 r  u    ​		g      I@u    r   )'get_run_iteratorr   rP  r  rK  r   rS   rP   rF  ConstRunIteratorr   rU   r  r   r>   r   r?   r@   rA   r  zipr6   r   r3   r,   r   r-   r   r$   r/   r1   r2   rB   
IndexErrorhasattrr   r   rl   get_font)(r&   r   r  r#   r   owner_iteratorfont_iteratoralign_iteratorwrap_iteratormargin_left_iteratormargin_right_iteratorindent_iteratorkerning_iteratortab_stops_iteratorrh   r  r2   rC   	run_accumrun_accum_widtheol_wsr   r   owner_accumowner_accum_widthowner_accum_commitowner_accum_commit_widthnokernindexr  r   r   runtab_stoptab
next_startnew_paragraphnew_linekgs(                                           r   r  zTextLayout._flow_glyphs_wrap  s	      $4466==eSII444CC 4N))'22>>  ;#4DM&''0 0MM $7--f55DD M  ':N))-88++Q 0  0 !( ;N)).99++Q!0 !0 "5N))(33++Q0 0 #6N)))44++Q0 0 %8N))+66++R1 1 U||#E*
//0DU0KLL 001Fu1MNNA::+EAI6+EE#'D  4 4_U5K L LLU# 	GK$"22T5FFE  	  !/ q	5 q	5E3 'D K !
 "$'($ F E
 "%T]%7c	%BF5QT9DU!V!V P Pu ID"FF//0@0GHHD6>>d.?&?&?( * *S)))) "I&'Ot||(:5(A S SH'+';';H'E'EH'!d.>*>>> %  ? #&C*+d.>*>3)F!(Ks'RH"8a<$2B#BU]#RSS&&e}555&--k:::,0AEM0QTX0XX,emd22F"$K()%--AQJE
 "'JJ$(K$7M $	 1CmH NO!1 NOa$h6NRW6W6W\d6W
 $ 0tv~~ (1 2 2 $S 1 1 1 1(*I./O.55kBBB48II4*,K01- KK1,KK).J' 0 *a
 . 9 LL )%7I*B!D !DE E E 24.784# 8DJ 8 +/+DK+/<DL  : $O $O JJ&0JJ, :59 2"&JJJ'',Z'8'8-;J-G
373G3G$8$D4F 4F 0484H4H$9*$E5G 5G 1 1#- ' ' ' !'	'
  - <7; 4  ) 	.WY-I-I 	.iN^ 	.'0|':1'=1:;Q	! 3A 6 /1 4!, .'21~123QA 1Q 6 1 1)- /2C CA#/ O)-)-)9*:<@<M*N "%66 2!((///'5=8U]*& 2,Z8(( 001LMMN((+ K%)[%)%5&68<8I&JE% 2 $**D%=999)U]T-AA)U]T11QJEFF " BYud4F'?A A B B B 5  5$+<"> "> ? ? ?#44  	 	CLLz 	(|~..qdi.@@+DK<DL




s   AU
U/.U/c           	   #     K   |                                                     ||          }| j                            | j                  }t          j        | j                            d          d d          }t          |          }|d         }	| j	        r<t          j        | j
                            d          d d          }
|
|         |_        |D ]\  }}}||         }	d}g }|                    ||          D ]a\  }}}|||         }|t          d |D                       z  }||||z
  z  z  }|                    t          |g||z
  z  |                     b||D ]\  }}|                    |           |                    t!          ||	||                     |j        s|	j        |_        |	j        |_        d	x|_        |_        |V  d S )
Nr  r  c                 
    | d uS r!   rE   rL   s    r   rM   z5TextLayout._flow_glyphs_single_line.<locals>.<lambda>  rN   r   r   r>   c                 
    | dv S r  rE   rL   s    r   rM   z5TextLayout._flow_glyphs_single_line.<locals>.<lambda>  s    e'BB r   r   c                     g | ]	}|j         
S rE   r   )rc  r  s     r   re  z7TextLayout._flow_glyphs_single_line.<locals>.<listcomp>  s    444Aai444r   T)r  r   rU   r  rK  r   rS   rP   r   rF  rP  r>   sumr   r  r6   r   r$   r/   r1   rA   rB   )r&   r   r  r#   r   r  r  kern_iteratorrh   r   r  r   r2   owner_glyphs
kern_startkern_endr   gsr   s                      r   r  z#TextLayout._flow_glyphs_single_line  s      #4466==eSII33	3BB3M((33++Q0 0 U||Q; 	/$8--g66BB N (.DJ!/ 	J 	JE3 'DEL.;.B.B5#.N.N O O*
HdJx/044444555J!677##C(Z2G(H"$M$MNNNN}#/ ( (KD%LL''''( YudL%HHIIIIz 	(+DK<DL488t1




r   c                    t          j        | j                            d          d d          }t          j        | j                            d          d d          }| j                            d          }t          j        | j                            d          d d          }|dk    rd}n||d	z
           }	|                     ||	j                           }
|                     ||	j                           }|	j        }|

||	j        z  }|	j        r#||                     ||	j                           z  }|}||d          D ]}	|	j	        rd||                     ||	j                           z  }|                     ||	j                           }
|                     ||	j                           }n||z  }|
||	j
        z  }n||
z  }|	j        d
k    s|	j        | j        k    r|	j        |	_        nb|	j        dk    r0| j        |	j        z
  |	j        z
  |	j        z
  dz  |	j        z   |	_        n'|	j        dk    r| j        |	j        z
  |	j        z
  |	_        t!          | j        |	j        |	j        z             | _        |	j        |k    r||k    r nL||	_        |

||	j        z  }|	j        r#||                     ||	j                           z  }|d	z  }| | _        |S )N
margin_topc                 
    | d uS r!   rE   rL   s    r   rM   z(TextLayout._flow_lines.<locals>.<lambda>  rN   r   r   margin_bottomc                 
    | d uS r!   rE   rL   s    r   rM   z(TextLayout._flow_lines.<locals>.<lambda>  rN   r   line_spacingleadingc                 
    | d uS r!   rE   rL   s    r   rM   z(TextLayout._flow_lines.<locals>.<lambda>  rN   r   r   r   r  r   r  )r   rS   rP  rP   r   r#   rD   r1   rB   rA   r/   r>   r2   r?   rC   r@   r.   r@  rA  )r&   r  r#   r   margin_top_iteratormargin_bottom_iteratorline_spacing_iteratorleading_iteratorrD   rh   r  r  
line_indexs                r   r  zTextLayout._flow_lines  s   %9N)),77++Q0 0 ")!<N))/::++Q"0 "0 !% = =n M M"6N)))44++Q0 0 A::AA#D//0Edj0QRRL**+;DJ+GHHGA#T\!! NT))*@*LMMM
%&&M #	% #	%D# T))*=dj*IJJJ#334I$*4UVV../?
/KLLW#T[ \!zV##tzDJ'>'>)x''*t'77$:KKdjX]^^aeaqqw&&d&77$*D!$T%7dFV9V!W!WDv{{zS00 DF#T\!! NT))*@*LMMM!OJJ#$"Dr   c                 j    |D ]/}|                     | ||||           ||j        z  }||j        z  }0d S r!   )rv   r3   r-   )r&   rC   rD   rt   r$   ru   r5   s          r   r  zTextLayout._create_vertex_lists  sN     	 	CIIdAq!W---AOAA	 	r   )NNFNNNT)Hr;   r<   r=   r   rP  r\   r]   r   r  r   r  r   r+  r   r0  r   r  rD  r  r[  ri  rF  rG  r  r  r  rH  rz  r'   r(  r   rU   r)  r   rC   r^  rD   rk  r   ru  r{  r2   r   rL  r  r  r  rJ  r   r  r  r8   r  rB  r  rX  r  r  r  r  rU  rS  r  r  r  r  r  r  r  r  r  r  rE   r   r   r<  r<    sI        < IMF!!I,x,Q	::00I>>"E"Ea"S"SOJN	
B	
BFGIIOJH48>B 4! 4! 4! 4!l   X 	 	 X	 _  _ 	 	 X	 \  \   X X  X
 
 
   X X  X
 
 
     X  _  _  0   X ^  ^   X \  \
   X ]  ] 	 	 X	   
   X* _  _   X4 _  _ $ $ X$.   6 6 64 4 4
% % %    
8 
8 
8f f f  d d d<. . .T T T` ` `>` ` `    " " "" " "	" 	" 	"  	2 	2 	2  } } }~' ' 'R? ? ?B    r   r<  c                       e Zd ZdZd fd	Zd Zed             Zej         fd            Zed	             Z	e	j         fd
            Z	ed             Z
e
j        d             Z
ed             Zej         fd            Zed             Zej         fd            Zed             Zej        d             Zed             Zej        d             Z xZS )ScrollableTextLayouta  Display text in a scrollable viewport.

    This class does not display a scrollbar or handle scroll events; it merely
    clips the text that would be drawn in :py:func:`~pyglet.text.layout.TextLayout`
    to the bounds of the layout given by `x`, `y`, `width` and `height`;
    and offsets the text by a scroll offset.

    Use `view_x` and `view_y` to scroll the text within the viewport.
    FNTc	           
          t                                          ||||||||           | j        | j        _        | j        | j        _        d S r!   )r[   r'   rF  r  r2   rG  r   
r&   rU   r2   r   rL  r   r   r   rM  r^   s
            r   r'   zScrollableTextLayout.__init__  sH    5&)S%PZ[[[#{ $r   c                     t          |          | _        t          j        d| j                  | _        t          d| j                  | _        t          d| j                  | _        d S r  )	r   r  r   r  r   r+  r   r0  r   r  s     r   rB  z!ScrollableTextLayout._init_groups   sX    2599 ( 5a H H 9!T^ L L+NqRVR`+a+a(((r   c                     | j         S r!   rZ  r)   s    r   rC   zScrollableTextLayout.x	  	    wr   c                     t                                          |           |                                 | j        _        d S r!   )r[   r^  r  r  rC   )r&   rC   r^   s     r   rC   zScrollableTextLayout.x  s3    q>>++r   c                     | j         S r!   rh  r)   s    r   rD   zScrollableTextLayout.y  r-  r   c                 b    t                                          |           || j        _        d S r!   )r[   rk  r  rD   )r&   rD   r^   s     r   rD   zScrollableTextLayout.y  s)    qr   c                     | j         | j        fS r!   rs  r)   s    r   r   zScrollableTextLayout.position      wr   c                 $    |\  | _         | _        d S r!   rC   rD   r~   s     r   r   zScrollableTextLayout.position      !r   c                     | j         S r!   r  r)   s    r   r  zScrollableTextLayout.anchor_x#  
    ~r   c                     || _         t                                                       |                                 | j        _        d S r!   )r  r[   rX  r  r  rC   )r&   r  r^   s     r   r  zScrollableTextLayout.anchor_x'  s8    !>>++r   c                     | j         S r!   r  r)   s    r   r  zScrollableTextLayout.anchor_y-  r7  r   c                     || _         t                                                       |                     |                                           | j        _        d S r!   )r  r[   rX  r  r  r  rD   )r&   r  r^   s     r   r  zScrollableTextLayout.anchor_y1  sF    !++DOO,=,=>>r   c                     | j         j        S aH  Horizontal scroll offset.

        The initial value is 0, and the left edge of the text will touch the left
        side of the layout bounds.  A positive value causes the text to "scroll"
        to the right.  Values are automatically clipped into the range
        ``[0, content_width - width]``

        :type: int
        r  r   r)   s    r   r   zScrollableTextLayout.view_x9       ~$$r   c                 t    t          dt          | j        | j        z
  |                    }|| j        _        d S r   r.   r0   r@  r2   r  r   r!  s     r   r   zScrollableTextLayout.view_xF  5    QD.;VDDEE &r   c                     | j         j        S a  Vertical scroll offset.

        The initial value is 0, and the top of the text will touch the top of the
        layout bounds (unless the content height is less than the layout height,
        in which case `content_valign` is used).

        A negative value causes the text to "scroll" upwards.  Values outside of
        the range ``[height - content_height, 0]`` are automatically clipped in
        range.

        :type: int
        r  r   r)   s    r   r   zScrollableTextLayout.view_yK       ~$$r   c                 t    t          dt          | j        | j        z
  |                    }|| j        _        d S r   )r0   r.   r   rA  r  r   r%  s     r   r   zScrollableTextLayout.view_y[  s7     QDK$*==vFFGG &r   FNNNT)r;   r<   r=   r   r'   rB  r(  rC   r)  rD   r   r  r  r   r   rc   rd   s   @r   r(  r(    s	        - - - - - -
b b b   X X, , , , X,   X X    X     X  _" " _"   X _, , , , _,
   X _? ? ? ? _? 
% 
% X
% ]' ' ]' % % X% ]' ' ]' ' ' ' 'r   r(  c                       e Zd ZdZdZdZg dZg dZdZd? f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ed             Zej        d             Zed             Zej        d             Zed             Zej        d             Zed             Zej        d             Zed             Zej        d              Zed!             Zej         fd"            Zed#             Z e j         fd$            Z ed%             Z!e!j        d&             Z!ed'             Z"e"j        d(             Z"ed)             Z#e#j        d*             Z#d+ Z$ed,             Z%e%j        d-             Z%ed.             Z&e&j        d/             Z&ed0             Z'e'j        d1             Z'ed2             Z(e(j        d3             Z(d4 Z)d@d5Z*d6 Z+d7 Z,d8 Z-d9 Z.d: Z/d; Z0d< Z1d= Z2e3rd> Z4 xZ5S  xZ5S )AIncrementalTextLayouta  Displayed text suitable for interactive editing and/or scrolling
    large documents.

    Unlike :py:func:`~pyglet.text.layout.TextLayout` and
    :py:class:`~pyglet.text.layout.ScrollableTextLayout`, this class generates
    vertex lists only for lines of text that are visible.  As the document is
    scrolled, vertex lists are deleted and created as appropriate to keep
    video memory usage to a minimum and improve rendering speed.

    Changes to the document are quickly reflected in this layout, as only the
    affected line(s) are reflowed.  Use `begin_update` and `end_update` to
    further reduce the amount of processing required.

    The layout can also display a text selection (text with a different
    background color).  The :py:class:`~pyglet.text.caret.Caret` class implements a visible text cursor and
    provides event handlers for scrolling, selecting and editing text in an
    incremental text layout.
    r   )r   r   r   r   ).   j      r   FNTc	           
      Z   g | _         g | _        t                      | _        t                      | _        t                      | _        t                      | _        t                      | _        t                      | _        t          j
        dd           | _        t                                          ||||||||           || j        _        |                                 | j        _        || j        _        |                     |                                           | j        _        d S r   )r   r  r   invalid_glyphsinvalid_flowinvalid_linesinvalid_styleinvalid_vertex_linesvisible_linesr   r  r  r[   r'   r  r2   r  r   r   r  r  r  r*  s
            r   r'   zIncrementalTextLayout.__init__|  s    
+oo)OO*__*__$1OO!*__!/!T225&)S%PZ[[[$"nn.. &!]]4??+<+<==r   c                     t          |          | _        t          j        d| j                  | _        t          d| j                  | _        t          d| j                  | _        d S r  )	r  r  r   r  r   r+  r   r0  r   r  s     r   rB  z"IncrementalTextLayout._init_groups  sX    3E:: ( 5a H H 9!T^ L L+NqRVR`+a+a(((r   c                 h    | j         s
J d            |                     d| j         j                   d S )Nz1Cannot remove document from IncrementalTextLayoutr   )rP  r  r  r)   s    r   rU  z$IncrementalTextLayout._init_document  s9    ~RRRRR~At~233333r   c                 `    |                      dt          | j        j                             d S r   )r  r   rP  r  r)   s    r   rS  z&IncrementalTextLayout._uninit_document  s+    As4>#67788888r   c                     | j         S r!   )r  r)   s    r   r  z IncrementalTextLayout._get_lines  s
    zr   c                     | j         D ]}|                    |            d | _        | j        r| j                            |            d | _        d S r!   )r  r8   rE  rP  rR  r&   rh   s     r   r8   zIncrementalTextLayout.delete  sZ    J 	 	DKK> 	1N**4000r   c                    t          |          }d g|z  | j        ||<   | j                            ||           | j                            ||           | j                            ||           | j                            ||           | j        D ]}|j        |k    r|xj        |z  c_        | 	                                 d S r!   )
r   r   rN  r   rO  rQ  r  r  r#   rX  )r&   r#   r  r  rh   s        r   r  z$IncrementalTextLayout.on_insert_text  s    t99$(6H#4E%K ""5(333  111!!%222uh///J 	' 	'DzU""

h&

r   c                    g | j         ||<   | j                            ||           | j                            ||           | j                            ||           | j                            ||           ||z
  }| j        D ]*}|j        |k    rt          |j        |z
  |          |_        +|dk    r| j        	                    dd           n| j        	                    |dz
  |           | 
                                 d S r   )r   rN  r8   rO  rQ  r  r  r#   r.   r   rX  )r&   r#   r   sizerh   s        r   r  z$IncrementalTextLayout.on_delete_text  s   !#E#I""5#...  ,,,!!%---uc***U{J 	; 	;DzE!! d!2E::
A::((A....((E:::r   c                    d|v sd|v sd|v sd|v r| j                             ||           n?d|v sd|v r| j                            ||           n| j                            ||           |                                  d S )N	font_name	font_sizebolditalicr   r  )rN  r   rQ  rO  rX  r  s       r   r  z#IncrementalTextLayout.on_style_text  s    *$$z(A(AVzEYEY]eis]s]s**5#6666
""&8J&F&F))%5555((444r   c                 4   | j         sd S | j                                        p1| j                                        p| j                                        }| j        s| j        D ]}|                    |            | j        d d = | j                            t          d                     | j
                            d| j                  }|j        | j        d         _        |j        | j        d         _        dx| j        d         _        | j        d         _        | j                            dd           |                                  |                                  |                                  |                                  |                                  |                     | j                  | j        _        | j        | _        |                     |                                           | j        _        |r|                     d           d S d S )Nr   r  Tr   on_layout_update)r  rN  r   rO  rP  r   r  r8   r,   r   rU   r  rK  r/   r1   rA   rB   r   _update_glyphs_update_flow_glyphs_update_flow_lines_update_visible_lines_update_vertex_listsr  r  r  r   r  dispatch_event)r&   trigger_update_eventrh   r   s       r   rX  zIncrementalTextLayout._update  s   # 	F $ 3 > > @ @ !@ $ 1 < < > >!@ $ 2 = = ? ? 	
 { 		0
 " "D!!!!
111JeAhh'''=))!);;D#';DJqM $(LDJqM!JNNDJqM)DJqM,G))!Q///  """!!!""$$$!!###!]]4:66 k!]]4??+<+<== 	4 233333	4 	4r   c                 8   | j                                         \  }}||z
  dk    rd S | j        j        }|dk    r+t	          ||dz
           ||                   rn|dz  }|dk    +t          |          }||k     r+t	          ||dz
           ||                   rn|dz  }||k     +t          j        | j        	                    | j
                  | j                                        f          }|                    ||          D ]V\  }}\  }}	|	rt          |	          | j        |<   #| j        j        ||         }|                    |          | j        ||<   W|                     | j        | j        ||           | j                            ||           d S )Nr   r   r  )rN  r   rU   r  r   r   r   rQ   rP  r  rK  r  r   r   r   r  r  r  rO  r   )
r&   invalid_startinvalid_endr  r  r  r#   r   r   r   s
             r   rd  z$IncrementalTextLayout._update_glyphs  s   %)%8%A%A%C%C"{&!++F }!atMA$56]8KLL QM a
 t99H$$tK!O4d;6GHH 1K H$$ %N((TY(77N++--'/ 0 0 ,0;;}k+R+R 	? 	?'E3w ?%6w%?%?E""})%)4)-)>)>E#I&& 	T_dk=+VVV 	$$]K@@@@@r   c                 :   | j                                         \  }}||z
  dk    rd S d}t          | j                  D ]\  }}|j        |k    r n|}t          d|dz
            }	 | j        |         }t          ||j                  }|                    |            t          |          x}| j        |<   | j	        
                    ||dz              nX# t          $ rK d}d}t          d          }| j                            |           | j	                            dd           Y nw xY wd}|}|                     | j        | j        |t#          | j        j                            D ]
}	 | j        |         }|                    |            |j        |j        z   }	|j        |j        z   }
|	| j        k    r|
|	k     rd}|| j        |<   | j	        
                    ||dz              nE# t          $ r8 | j                            |           | j	                            |d           Y nw xY w|j        |j        z   }|dz  }	 | j        |         }||j        k    r||k    r n# t          $ r Y w xY w|t#          | j        j                  k    rS|dk    rM| j        |d          D ]3}|j        |j        z   }	|	| j        k    rd}|                    |            4| j        |d = |r2d}| j        D ]}t          |j        |j        z   |          } || _        d S d S )Nr   r   FT)rO  r   r  r  r#   r.   r0   r8   r   rP  r   r  r,   r   r  r   r  r   rP  r  r2   r?   r@  r-   )r&   rl  rm  r%  rt   rh   content_width_invalidr
  old_lineold_line_widthnew_line_width	next_liner@  s                r   re  z)IncrementalTextLayout._update_flow_glyphs  s   %)%6%?%?%A%A"{&!++F 
 ,, 	 	GAtz]**JJ JN++

	,:j)Dtz::MKK,1-,@,@@D4:j)))*j1nEEEE 	, 	, 	,JM88DJd###%%a+++++	, !&"
%%dk4?MSVW[WeWjSkSkll !	, !	,D9:j1%%%!)(2F!F!%d.>!>!T%777N^<[<[,0))-
:&"--j*q.IIII 9 9 9
!!$'''"))*a888889 dk1J!OJ Jz2	00Z+5M5ME   
 S!45555*q.. Jz{{3 & &D%-^h6J%JN%);;;04-KK%%%%Jz{{+  	/M
 R R #DJ1A$A= Q Q!.D	/ 	/s9   'A.C AD+*D+/A;G++?H-,H-I&&
I43I4c                     | j                                         \  }}||z
  dk    rd S |                     | j        ||          }| j                            ||           d S r   )rP  r   r  r  rR  r   )r&   rl  rm  s      r   rf  z(IncrementalTextLayout._update_flow_lineso  sj    %)%7%@%@%B%B"{&!++F&&tz=+NN 	!,,]KHHHHHr   c           	      D   t           j        }d}t          | j                  D ]`\  }}|j        |j        z   | j        k     rt          ||          }|j        |j        z   | j        | j	        z
  k    rt          ||          dz   }at          | j        j        t          |t          | j                                      D ]"}| j        |                             |            #t          |t          | j        j        t          | j                                      D ]"}| j        |                             |            #| j                            || j        j                   | j                            | j        j        |           || j        _        || j        _        d S r   )r   r   r  r  rD   r1   r   r0   r/   r   r.   rangerS  r#   r   r8   r   rR  r   )r&   r#   r   rt   rh   s        r   rg  z+IncrementalTextLayout._update_visible_linesy  sw    ,, 	& 	&GAtv$t{22E1v#dkDK&???#qkkAo t)/UC
OO1L1LMM 	' 	'AJqM  &&&&sC 2 6DJHHII 	' 	'AJqM  &&&& 	!,,UD4F4LMMM!,,T-?-CSIII#( !$r   c                    | j                                         \  }}| j                            |                     |          |                     |          dz              | j                                        \  }}||z
  dk    rd S | j                            d          }| j                            d          }| j        | j        z
  dk    rLt          j
        || j        | j        | j                  }t          j
        || j        | j        | j                  }t          | | j        ||          }| j        ||         D ]}|                    |            ||_        |j        }	|	|j        z   | j        k    r9|	|j        z   | j        | j        z
  k     r d S |                     |j        |	|j        |j        |           d S )Nr   r   r   r  )rQ  r   rR  r   get_line_from_positionrU   rP   _selection_end_selection_startr   OverriddenRunIterator_selection_color_selection_background_colorrf   rP  r  r8   rh   rD   r1   r   r/   r   r  rC   r#   r$   )
r&   style_invalid_startstyle_invalid_endrl  rm  rO   rV   ru   rh   rD   s
             r   rh  z*IncrementalTextLayout._update_vertex_lists  s   151C1L1L1N1N..!,,''(;<<''(9::Q>	@ 	@ 	@ &*%>%G%G%I%I"{&!++Fm227;;-667IJJ!66::!7%#%	' 'K
 &;%#0	2 2O ,D$.+__J}[89 	R 	RDKKGLA 4<$+--T[4;#<<<%%dfaTZQQQQ	R 	Rr   c                     | j         S r!   rZ  r)   s    r   rC   zIncrementalTextLayout.x  r-  r   c                 P    || _         |                                 | j        _        d S r!   )r[  r  r  r   r{   s     r   rC   zIncrementalTextLayout.x  s#    "nn..r   c                     | j         S r!   rh  r)   s    r   rD   zIncrementalTextLayout.y  r-  r   c                 v    || _         |                     |                                           | j        _        d S r!   )ri  r  r  r  r  rl  s     r   rD   zIncrementalTextLayout.y  s/    !]]4??+<+<==r   c                     | j         | j        fS r!   rs  r)   s    r   r   zIncrementalTextLayout.position  r2  r   c                 $    |\  | _         | _        d S r!   r4  r~   s     r   r   zIncrementalTextLayout.position  r5  r   c                     | j         S r!   r  r)   s    r   r  zIncrementalTextLayout.anchor_x  r7  r   c                 P    || _         |                                 | j        _        d S r!   )r  r  r  r   r  s     r   r  zIncrementalTextLayout.anchor_x  s#    !"nn..r   c                     | j         S r!   r  r)   s    r   r  zIncrementalTextLayout.anchor_y  r7  r   c                 v    || _         |                     |                                           | j        _        d S r!   )r  r  r  r  r  r  s     r   r  zIncrementalTextLayout.anchor_y  s/    !!]]4??+<+<==r   c                     | j         S r!   r~  r)   s    r   r2   zIncrementalTextLayout.width  s
    {r   c                 2   || j         k    rd S || _         t                                                       | j                            dt          | j        j                             |                                 | j	        _
        | j         | j	        _        d S r   )rF  r[   rX  rO  r   r   rU   r  r  r  r   r2   )r&   r2   r^   s     r   r2   zIncrementalTextLayout.width  s~     DKF$$QDM,>(?(?@@@"nn..#{r   c                     | j         S r!   r  r)   s    r   r   zIncrementalTextLayout.height  r  r   c                 V   || j         k    rd S || _         t                                                       |                     |                                           | j        _        | j         | j        _        | j        r*| 	                                 | 
                                 d S d S r!   )rG  r[   rX  r  r  r  r  r   r  rg  rh  )r&   r   r^   s     r   r   zIncrementalTextLayout.height  s     T\!!F!]]4??+<+<== $ 	(&&(((%%'''''	( 	(r   c                     | j         S r!   r  r)   s    r   rL  zIncrementalTextLayout.multiline	  s
    r   c                     | j                             dt          | j        j                             || _        |                                  |                                  d S r   )rO  r   r   rU   r  rH  rJ  rX  r  s     r   rL  zIncrementalTextLayout.multiline	  sR    $$QDM,>(?(?@@@#""$$$r   c                     | j         j        S r<  r=  r)   s    r   r   zIncrementalTextLayout.view_x	  r>  r   c                 t    t          dt          | j        | j        z
  |                    }|| j        _        d S r   r@  r!  s     r   r   zIncrementalTextLayout.view_x	  rA  r   c                     | j         j        S rC  rD  r)   s    r   r   zIncrementalTextLayout.view_y 	  rE  r   c                     t          dt          | j        | j        z
  |                    }|| j        _        |                                  |                                  d S r   )r0   r.   r   rA  r  r   rg  rh  r%  s     r   r   zIncrementalTextLayout.view_y0	  s[     QDK$*==vFFGG &""$$$!!#####r   c                    t          d|          }t          |t          | j        j                            }|| j        k    r|| j        k    rdS || j        k    r|| j        k     r| j                            t          || j                  t          || j                             | j                            t          || j                  t          || j                             n@| j                            | j        | j                   | j                            ||           || _        || _        | 	                                 dS )a  Set the text selection range.

        If ``start`` equals ``end`` no selection will be visible.

        :Parameters:
            `start` : int
                Starting character position of selection.
            `end` : int
                End of selection, exclusive.

        r   N)
r.   r0   r   rU   r  rz  ry  rQ  r   rX  r   s      r   set_selectionz#IncrementalTextLayout.set_selection;	  sJ    Au#s4=-..//D)))cT5H.H.HF&&&543F+F+F))#eT5J*K*K*-eT5J*K*KM M M))#c43F*G*G*-c43F*G*GI I I I ))$*?*.*=? ? ?))%555 %!r   c                     | j         S )zfStarting position of the active selection.

        :see: `set_selection`

        :type: int
        )rz  r)   s    r   selection_startz%IncrementalTextLayout.selection_start]	       $$r   c                 <    |                      || j                   d S r!   )r  ry  r%   s     r   r  z%IncrementalTextLayout.selection_startg	  s!    5$"566666r   c                     | j         S )zmEnd position of the active selection (exclusive).

        :see: `set_selection`

        :type: int
        )ry  r)   s    r   selection_endz#IncrementalTextLayout.selection_endk	  s     ""r   c                 <    |                      | j        |           d S r!   )r  rz  )r&   r   s     r   r  z#IncrementalTextLayout.selection_endu	  s!    40#66666r   c                     | j         S )zText color of active selection.

        The color is an RGBA tuple with components in range [0, 255].

        :type: (int, int, int, int)
        )r|  r)   s    r   selection_colorz%IncrementalTextLayout.selection_colory	  r  r   c                 ^    || _         | j                            | j        | j                   d S r!   )r|  rQ  r   rz  ry  )r&   r   s     r   r  z%IncrementalTextLayout.selection_color	  s/     %%%d&;T=PQQQQQr   c                     | j         S )zBackground color of active selection.

        The color is an RGBA tuple with components in range [0, 255].

        :type: (int, int, int, int)
        )r}  r)   s    r   selection_background_colorz0IncrementalTextLayout.selection_background_color	  s     //r   c                 ^    || _         | j                            | j        | j                   d S r!   )r}  rQ  r   rz  ry  )r&   r  s     r   r  z0IncrementalTextLayout.selection_background_color	  s/    +;(%%d&;T=PQQQQQr   c                 Z    |                      ||          }|                     ||          S )zGet the closest document position to a point.

        :Parameters:
            `x` : int
                X coordinate
            `y` : int
                Y coordinate

        )get_line_from_pointget_position_on_line)r&   rC   rD   rh   s       r   get_position_from_pointz-IncrementalTextLayout.get_position_from_point	  s/     ''1--((q111r   c                    |'| j         d         }| j         D ]}|j        |k    r n|}n| j         |         }|j        }| j                            dt          d|dz
                      }|d}n|                     |          }||j        z  }|j        D ]>}||j        z
  dk    r||	                    |          z  } n||j        z  }||j
        z  }?|| j        j        z   |j        | j        j        z   |z   fS )a/  Get the X, Y coordinates of a position in the document.

        The position that ends a line has an ambiguous point: it can be either
        the end of the line, or the beginning of the next line.  You may
        optionally specify a line index to disambiguate the case.

        The resulting Y coordinate gives the baseline of the line.

        :Parameters:
            `position` : int
                Character position within document.
            `line` : int
                Line index.

        :rtype: (int, int)
        :return: (x, y)
        Nr   rJ   r   )r  r#   rC   rP  	get_styler.   r   r$   r-   r   r3   r  r   rD   r   )r&   r   rh   rs  rC   rJ   r5   s          r   get_point_from_positionz-IncrementalTextLayout.get_point_from_position	  s#   $ <:a=D!Z ! !	?X--E :d#DF>++JAx!|8L8LMMHH++H55HDJ: 	 	C#*$))S))(333
"HAA4>(($&4>3H*H8*SSSr   c                     || j         j        z  }|| j         j        z  }d}| j        D ]}||j        |j        z   k    r n|dz  }|t          | j                  k    rt          | j                  dz
  }|S )zGet the closest line index to a point.

        :Parameters:
            `x` : int
                X coordinate.
            `y` : int
                Y coordinate.

        :rtype: int
        r   r   )r  r  r  r  rD   r1   r   )r&   rC   rD   r%  rh   s        r   r  z)IncrementalTextLayout.get_line_from_point	  s     	
T^''	T^''
J 	 	D46DL(((!OJJTZ((TZ1,Jr   c                 l    | j         |         }|j        | j        j        z   |j        | j        j        z   fS )zGet the X, Y coordinates of a line index.

        :Parameters:
            `line` : int
                Line index.

        :rtype: (int, int)
        :return: (x, y)
        )r  rC   r  r  rD   r  rY  s     r   get_point_from_linez)IncrementalTextLayout.get_point_from_line	  s3     z$v22DFT^=W4WWWr   c                 B    d}| j         D ]}|j        |k    r n|dz  }|S )zGet the line index of a character position in the document.

        :Parameters:
            `position` : int
                Document position.

        :rtype: int
        r   r  r#   )r&   r   rh   rs  s       r   rx  z,IncrementalTextLayout.get_line_from_position	  s<      	 	I))AIDDr   c                 &    | j         |         j        S )zGet the first document character position of a given line index.

        :Parameters:
            `line` : int
                Line index.

        :rtype: int
        r  rY  s     r   get_position_from_linez,IncrementalTextLayout.get_position_from_line
  s     z$%%r   c                 $   | j         |         }|| j        j        z  }||j        k     r|j        S |j        }|j        }|j        D ]K}d||z
  cxk    r|j        k     r n n||                    ||z
            z  } n||j        z  }||j        z  }L|S )zGet the closest document position for a given line index and X
        coordinate.

        :Parameters:
            `line` : int
                Line index.
            `x` : int
                X coordinate.

        :rtype: int
        r   )	r  r  r  rC   r#   r$   r3   r|   r-   )r&   rh   rC   r   r   r5   s         r   r  z*IncrementalTextLayout.get_position_on_line
  s     z$	T^''tv::::v: 	# 	#CA$2222s{22222C33A4DEEECK'L
"HHr   c                 *    t          | j                  S )zIGet the number of lines in the text layout.

        :rtype: int
        )r   r  r)   s    r   get_line_countz$IncrementalTextLayout.get_line_count/
  s    
 4:r   c                     | j         |         }|j        |j        z   }|j        |j        z   }|| j        k    r	|| _        dS || j        | j        z
  k     r|| j        z   | _        dS dS )zAdjust `view_y` so that the line with the given index is visible.

        :Parameters:
            `line` : int
                Line index.

        N)r  rD   r/   r1   r   r   )r&   rh   r   r   s       r   ensure_line_visiblez)IncrementalTextLayout.ensure_line_visible6
  sr     z$Vdk!Vdl"DKKK$++++t{*DKKK ,+r   c                     || j         dz   k    r|dz
  | _         dS || j         | j        z   k    r|| j        z
  dz   | _         dS || j         | j        z   dz
  k    r$| j        | j        k    r|| j        z
  dz   | _         dS dS dS )zAdjust `view_x` so that the given X coordinate is visible.

        The X coordinate is given relative to the current `view_x`.

        :Parameters:
            `x` : int
                X coordinate

        
   N)r   r2   r@  r{   s     r   ensure_x_visiblez&IncrementalTextLayout.ensure_x_visibleF
  s     b   b&DKKK$+
***dj.2-DKKK$+
*R///D4F4S4Sdj.2-DKKK 0/4S4Sr   c                     dS )a  Some or all of the layout text was reflowed.

            Text reflow is caused by document edits or changes to the layout's
            size.  Changes to the layout's position or active selection, and
            certain document edits such as text color, do not cause a reflow.

            Handle this event to update the position of a graphical element
            that depends on the laid out position of a glyph or line.

            :event:
            NrE   r)   s    r   rc  z&IncrementalTextLayout.on_layout_updateX
  s      r   rG  r!   )6r;   r<   r=   r   rz  ry  r|  r}  r  r'   rB  rU  rS  r  r8   r  r  r  rX  rd  re  rf  rg  rh  r(  rC   r)  rD   r   r  r  r2   r   rL  r   r   r  r  r  r  r  r  r  r  r  rx  r  r  r  r  r  _is_pyglet_doc_runrc  rc   rd   s   @r   rI  rI  b  sj        $ N+++"5"5"5N> > > > > >*b b b4 4 49 9 9         *   4  4  4D"A "A "AHN/ N/ N/`I I I% % %,&R &R &RP   X X/ / X/   X X> > X>     X  _" " _"   X _/ / _/   X _> > _>   X \+ + + + \+   X ]
( 
( 
( 
( ]
(   X    
% 
% X
% ]' ' ]' % % X% ]$ $ ]$     D % % X% 7 7 7 # # X# 7 7 7 % % X% R R R 0 0 X0  &R R '&R2 2 2+T +T +T +TZ  .X X X   	& 	& 	&  :  + + + . . ."  	 	 	 	 	 	 	   r   rI  rc  )&r   rer   	pyglet.glpygletr   r   pyglet.textr   pyglet.font.baser   r  r   r  compiler   r   r   rG   rY   rf   rl   r   r   r   Groupr   r   r  r  r+  r0  r   r<  r(  EventDispatcherrI  register_event_typerE   r   r   <module>r     s  Hv vp 
			 



                       , , , , , ,WS"566P3;P rz2338 8 8@& & & & & & & &R0 0 0 0 0 0 0 0
 
 
 
 
> 
 
 
       . . . . . . . .,D- D- D- D- D- D- D- D-N 6  6  6  6  6  6  6  6F#% #% #% #% #% #% #% #%`A A A A Ahn A A A4" " " " " " " "Jq q q q q q q qh          5      ! ! ! ! !(*? ! ! !V V V V VX^ V V V>} } } } } } } }@ o' o' o' o' o': o' o' o'dA A A A AJ(= A A AH  ) )*< = = = = =r   