mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 11:22:45 +00:00 
			
		
		
		
	 5a04472470
			
		
	
	
		5a04472470
		
	
	
	
	
		
			
			This code was using the text from the DOM as a reference for how much whitespace to remove from the end of a line box. Since the DOM may contain uncollapsed whitespace, it would sometimes be out of sync with the collapsed text used by the rest of the layout system.
		
			
				
	
	
		
			50 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			50 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <LibGUI/GPainter.h>
 | |
| #include <LibHTML/Layout/LayoutDocument.h>
 | |
| #include <LibHTML/Layout/LayoutText.h>
 | |
| #include <LibHTML/Layout/LineBoxFragment.h>
 | |
| #include <LibHTML/RenderingContext.h>
 | |
| 
 | |
| void LineBoxFragment::render(RenderingContext& context)
 | |
| {
 | |
|     for (auto* ancestor = layout_node().parent(); ancestor; ancestor = ancestor->parent()) {
 | |
|         if (!ancestor->is_visible())
 | |
|             return;
 | |
|     }
 | |
| 
 | |
|     if (is<LayoutText>(layout_node())) {
 | |
|         to<LayoutText>(layout_node()).render_fragment(context, *this);
 | |
|     }
 | |
| }
 | |
| 
 | |
| bool LineBoxFragment::is_justifiable_whitespace() const
 | |
| {
 | |
|     return text() == " ";
 | |
| }
 | |
| 
 | |
| StringView LineBoxFragment::text() const
 | |
| {
 | |
|     if (!is<LayoutText>(layout_node()))
 | |
|         return {};
 | |
|     return to<LayoutText>(layout_node()).text_for_rendering().substring_view(m_start, m_length);
 | |
| }
 | |
| 
 | |
| int LineBoxFragment::text_index_at(float x) const
 | |
| {
 | |
|     if (!layout_node().is_text())
 | |
|         return 0;
 | |
|     auto& layout_text = to<LayoutText>(layout_node());
 | |
|     auto& font = layout_text.style().font();
 | |
|     Utf8View view(text());
 | |
| 
 | |
|     float relative_x = x - m_rect.location().x();
 | |
|     float glyph_spacing = font.glyph_spacing();
 | |
| 
 | |
|     float width_so_far = 0;
 | |
|     for (auto it = view.begin(); it != view.end(); ++it) {
 | |
|         float glyph_width = font.glyph_or_emoji_width(*it);
 | |
|         if ((width_so_far + glyph_width + glyph_spacing) > relative_x)
 | |
|             return m_start + view.byte_offset_of(it);
 | |
|         width_so_far += glyph_width + glyph_spacing;
 | |
|     }
 | |
|     return m_start + m_length - 1;
 | |
| }
 |