2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2021 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 20:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2022 ,  Tobias  Christiansen  < tobyase @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/CharacterTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:36:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-02-10 08:25:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibGfx/Painter.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/Document.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-11-18 15:01:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/HTML/BrowsingContext.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-06 20:02:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/BlockContainer.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-12-05 20:10:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/InlineFormattingContext.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/Label.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TextNode.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-10 16:46:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Painting/TextPaintable.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  Web : : Layout  {  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TextNode : : TextNode ( DOM : : Document &  document ,  DOM : : Text &  text )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  Node ( document ,  & text ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-06 11:09:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_inline ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TextNode : : ~ TextNode ( )  
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-06-15 23:17:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:55:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_all_whitespace ( StringView  string )  
						 
					
						
							
								
									
										
										
										
											2019-06-15 23:17:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-12-09 17:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  string . length ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is_ascii_space ( string [ i ] ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 23:17:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:44:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : paint_text_decoration ( Gfx : : Painter &  painter ,  LineBoxFragment  const &  fragment )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Gfx : : IntPoint  line_start_point  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Gfx : : IntPoint  line_end_point  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  font  =  fragment . layout_node ( ) . font ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  fragment_box  =  enclosing_int_rect ( fragment . absolute_rect ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  glyph_height  =  font . glyph_height ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  baseline  =  fragment_box . height ( )  /  2  -  ( glyph_height  +  4 )  /  2  +  glyph_height ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( computed_values ( ) . text_decoration_line ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationLine : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationLine : : Underline : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_start_point  =  fragment_box . top_left ( ) . translated ( 0 ,  baseline  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_end_point  =  fragment_box . top_right ( ) . translated ( 0 ,  baseline  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationLine : : Overline : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_start_point  =  fragment_box . top_left ( ) . translated ( 0 ,  baseline  -  glyph_height ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_end_point  =  fragment_box . top_right ( ) . translated ( 0 ,  baseline  -  glyph_height ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationLine : : LineThrough :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  x_height  =  font . x_height ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_start_point  =  fragment_box . top_left ( ) . translated ( 0 ,  baseline  -  x_height  /  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        line_end_point  =  fragment_box . top_right ( ) . translated ( 0 ,  baseline  -  x_height  /  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 08:34:12 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:44:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationLine : : Blink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Conforming user agents may simply not blink the text
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-01 13:21:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:44:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 00:25:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  line_color  =  computed_values ( ) . text_decoration_color ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 19:48:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  line_thickness  =  [ this ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        CSS : : Length  computed_thickness  =  computed_values ( ) . text_decoration_thickness ( ) . resolved ( * this ,  CSS : : Length ( 1 ,  CSS : : Length : : Type : : Em ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( computed_thickness . is_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  CSS : : InitialValues : : text_decoration_thickness ( ) . to_px ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  computed_thickness . to_px ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 20:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( computed_values ( ) . text_decoration_style ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationStyle : : Solid : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 23:08:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . draw_line ( line_start_point ,  line_end_point ,  line_color ,  line_thickness ,  Gfx : : Painter : : LineStyle : : Solid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 20:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationStyle : : Double : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 23:08:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( computed_values ( ) . text_decoration_line ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : TextDecorationLine : : Underline : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : TextDecorationLine : : Overline : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            line_start_point . translate_by ( 0 ,  - line_thickness  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            line_end_point . translate_by ( 0 ,  - line_thickness  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  CSS : : TextDecorationLine : : LineThrough : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            line_start_point . translate_by ( 0 ,  - line_thickness  /  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            line_end_point . translate_by ( 0 ,  - line_thickness  /  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        painter . draw_line ( line_start_point ,  line_end_point ,  line_color ,  line_thickness ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        painter . draw_line ( line_start_point . translated ( 0 ,  line_thickness  +  1 ) ,  line_end_point . translated ( 0 ,  line_thickness  +  1 ) ,  line_color ,  line_thickness ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 20:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationStyle : : Dashed : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 23:08:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . draw_line ( line_start_point ,  line_end_point ,  line_color ,  line_thickness ,  Gfx : : Painter : : LineStyle : : Dashed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 20:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationStyle : : Dotted : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 23:08:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . draw_line ( line_start_point ,  line_end_point ,  line_color ,  line_thickness ,  Gfx : : Painter : : LineStyle : : Dotted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 20:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CSS : : TextDecorationStyle : : Wavy : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 19:48:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . draw_triangle_wave ( line_start_point ,  line_end_point ,  line_color ,  line_thickness  +  1 ,  line_thickness ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 20:30:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:44:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 02:13:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : paint_fragment ( PaintContext &  context ,  const  LineBoxFragment &  fragment ,  Painting : : PaintPhase  phase )  const  
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:36:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  painter  =  context . painter ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 02:13:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( phase  = =  Painting : : PaintPhase : : Foreground )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 09:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  fragment_absolute_rect  =  fragment . absolute_rect ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:05:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . set_font ( font ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( document ( ) . inspected_node ( )  = =  & dom_node ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 09:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            context . painter ( ) . draw_rect ( enclosing_int_rect ( fragment_absolute_rect ) ,  Color : : Magenta ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  text  =  m_text_for_rendering ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  text_transform  =  computed_values ( ) . text_transform ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 14:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( text_transform  = =  CSS : : TextTransform : : Uppercase ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            text  =  m_text_for_rendering . to_uppercase ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 14:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( text_transform  = =  CSS : : TextTransform : : Lowercase ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            text  =  m_text_for_rendering . to_lowercase ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 09:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // FIXME: This is a hack to prevent text clipping when painting a bitmap font into a too-small box.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  draw_rect  =  enclosing_int_rect ( fragment_absolute_rect ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        draw_rect . set_height ( max ( draw_rect . height ( ) ,  font ( ) . glyph_height ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        painter . draw_text ( draw_rect ,  text . substring_view ( fragment . start ( ) ,  fragment . length ( ) ) ,  Gfx : : TextAlignment : : CenterLeft ,  computed_values ( ) . color ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:05:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  selection_rect  =  fragment . selection_rect ( font ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! selection_rect . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            painter . fill_rect ( enclosing_int_rect ( selection_rect ) ,  context . palette ( ) . selection ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Gfx : : PainterStateSaver  saver ( painter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            painter . add_clip_rect ( enclosing_int_rect ( selection_rect ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-26 09:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            painter . draw_text ( enclosing_int_rect ( fragment_absolute_rect ) ,  text . substring_view ( fragment . start ( ) ,  fragment . length ( ) ) ,  Gfx : : TextAlignment : : CenterLeft ,  context . palette ( ) . selection_text ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 00:21:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        paint_text_decoration ( painter ,  fragment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        paint_cursor_if_needed ( context ,  fragment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : paint_cursor_if_needed ( PaintContext &  context ,  const  LineBoxFragment &  fragment )  const  
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! browsing_context ( ) . is_focused_context ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 11:45:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! browsing_context ( ) . cursor_blink_state ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( browsing_context ( ) . cursor_position ( ) . node ( )  ! =  & dom_node ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-18 21:56:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: This checks if the cursor is before the start or after the end of the fragment. If it is at the end, after all text, it should still be painted.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( browsing_context ( ) . cursor_position ( ) . offset ( )  <  ( unsigned ) fragment . start ( )  | |  browsing_context ( ) . cursor_position ( ) . offset ( )  >  ( unsigned ) ( fragment . start ( )  +  fragment . length ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 14:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! fragment . layout_node ( ) . dom_node ( )  | |  ! fragment . layout_node ( ) . dom_node ( ) - > is_editable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 16:05:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  fragment_rect  =  fragment . absolute_rect ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  cursor_x  =  fragment_rect . x ( )  +  font ( ) . width ( fragment . text ( ) . substring_view ( 0 ,  browsing_context ( ) . cursor_position ( ) . offset ( )  -  fragment . start ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  cursor_top  =  fragment_rect . top ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  cursor_height  =  fragment_rect . height ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Gfx : : IntRect  cursor_rect ( cursor_x ,  cursor_top ,  1 ,  cursor_height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 21:19:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    context . painter ( ) . draw_rect ( cursor_rect ,  computed_values ( ) . color ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:36:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NOTE: This collapes whitespace into a single ASCII space if collapse is true. If previous_is_empty_or_ends_in_whitespace, it also strips leading whitespace.
  
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : compute_text_for_rendering ( bool  collapse ,  bool  previous_is_empty_or_ends_in_whitespace )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  data  =  dom_node ( ) . data ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! collapse  | |  data . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_text_for_rendering  =  data ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: A couple fast returns to avoid unnecessarily allocating a StringBuilder.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( data . length ( )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_ascii_space ( data [ 0 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( previous_is_empty_or_ends_in_whitespace ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_text_for_rendering  =  String : : empty ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                static  String  s_single_space_string  =  "   " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_text_for_rendering  =  s_single_space_string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_text_for_rendering  =  data ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  contains_space  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  c  :  data )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_ascii_space ( c ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            contains_space  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! contains_space )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_text_for_rendering  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  builder ( data . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  skip_over_whitespace  =  [ & index ,  & data ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( index  <  data . length ( )  & &  is_ascii_space ( data [ index ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + index ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( previous_is_empty_or_ends_in_whitespace ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        skip_over_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( index  <  data . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_ascii_space ( data [ index ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            builder . append ( '   ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            + + index ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            skip_over_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            builder . append ( data [ index ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + index ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_text_for_rendering  =  builder . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  TextNode : : wants_mouse_events ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-15 18:48:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  first_ancestor_of_type < Label > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TextNode : : handle_mousedown ( Badge < EventHandler > ,  const  Gfx : : IntPoint &  position ,  unsigned  button ,  unsigned )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-15 18:48:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  label  =  first_ancestor_of_type < Label > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! label ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-15 18:48:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    label - > handle_mousedown_on_label ( { } ,  position ,  button ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    browsing_context ( ) . event_handler ( ) . set_mouse_event_tracking_layout_node ( this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TextNode : : handle_mouseup ( Badge < EventHandler > ,  const  Gfx : : IntPoint &  position ,  unsigned  button ,  unsigned )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-15 18:48:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  label  =  first_ancestor_of_type < Label > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! label ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 11:45:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: Changing the state of the DOM node may run arbitrary JS, which could disappear this node.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtr  protect  =  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-15 18:48:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    label - > handle_mouseup_on_label ( { } ,  position ,  button ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    browsing_context ( ) . event_handler ( ) . set_mouse_event_tracking_layout_node ( nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TextNode : : handle_mousemove ( Badge < EventHandler > ,  const  Gfx : : IntPoint &  position ,  unsigned  button ,  unsigned )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-15 18:48:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto *  label  =  first_ancestor_of_type < Label > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! label ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-15 18:48:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    label - > handle_mousemove_on_label ( { } ,  position ,  button ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:55:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TextNode : : ChunkIterator : : ChunkIterator ( StringView  text ,  LayoutMode  layout_mode ,  bool  wrap_lines ,  bool  respect_linebreaks )  
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    :  m_layout_mode ( layout_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_wrap_lines ( wrap_lines ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:53:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_respect_linebreaks ( respect_linebreaks ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_utf8_view ( text ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_iterator ( m_utf8_view . begin ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_last_was_space  =  ! text . is_empty ( )  & &  is_ascii_space ( * m_utf8_view . begin ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < TextNode : : Chunk >  TextNode : : ChunkIterator : : next ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_iterator  = =  m_utf8_view . end ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  start_of_chunk  =  m_iterator ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( m_iterator  ! =  m_utf8_view . end ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        + + m_iterator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_last_was_newline )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // NOTE: This expression looks out for the case where we have
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       multiple newlines in a row. Because every output next()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       that's a newline newline must be prepared for in advance by
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       the previous next() call, we need to check whether the next
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       character is a newline here as well. Otherwise, the newline
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       becomes part of the next expression and causes rendering
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       issues.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_last_was_newline  =  m_iterator  ! =  m_utf8_view . end ( )  & &  * m_iterator  = =  ' \n ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  result  =  try_commit_chunk ( start_of_chunk ,  m_iterator ,  true ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: The checks after this need to look at the current iterator
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       position, which depends on not being at the end.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_iterator  = =  m_utf8_view . end ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // NOTE: When we're supposed to stop on linebreaks, we're actually
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       supposed to output two chunks: "content" and "\n". Since we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       can't output two chunks at once, we store this information as a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       flag to output the newline immediately at the earliest
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       opportunity.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:53:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_respect_linebreaks  & &  * m_iterator  = =  ' \n ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_last_was_newline  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( auto  result  =  try_commit_chunk ( start_of_chunk ,  m_iterator ,  false ) ;  result . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  result . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 13:06:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_wrap_lines  | |  m_layout_mode  = =  LayoutMode : : AllPossibleLineBreaks )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bool  is_space  =  is_ascii_space ( * m_iterator ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_space  ! =  m_last_was_space )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_last_was_space  =  is_space ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( auto  result  =  try_commit_chunk ( start_of_chunk ,  m_iterator ,  false ) ;  result . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return  result . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( start_of_chunk  ! =  m_utf8_view . end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Try to output whatever's left at the end of the text node.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  result  =  try_commit_chunk ( start_of_chunk ,  m_utf8_view . end ( ) ,  false ,  true ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 22:23:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Optional < TextNode : : Chunk >  TextNode : : ChunkIterator : : try_commit_chunk ( Utf8View : : Iterator  const &  start ,  Utf8View : : Iterator  const &  end ,  bool  has_breaking_newline ,  bool  must_commit )  const  
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_layout_mode  = =  LayoutMode : : OnlyRequiredLineBreaks  & &  ! must_commit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  byte_offset  =  m_utf8_view . byte_offset_of ( start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  byte_length  =  m_utf8_view . byte_offset_of ( end )  -  byte_offset ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( byte_length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  chunk_view  =  m_utf8_view . substring_view ( byte_offset ,  byte_length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  Chunk  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . view  =  chunk_view , 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-28 00:45:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            . start  =  byte_offset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . length  =  byte_length , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            . has_breaking_newline  =  has_breaking_newline , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . is_all_whitespace  =  is_all_whitespace ( chunk_view . as_string ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 16:46:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								OwnPtr < Painting : : Paintable >  TextNode : : create_paintable ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  Painting : : TextPaintable : : create ( * this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}