mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:52:45 +00:00 
			
		
		
		
	LibWeb: Port Layout::TextNode from DeprecatedString
This commit is contained in:
		
							parent
							
								
									6b32a1f18f
								
							
						
					
					
						commit
						56d10bf198
					
				
					 9 changed files with 37 additions and 35 deletions
				
			
		|  | @ -372,7 +372,7 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho | |||
|                     for (size_t i = 0; i < indent; ++i) | ||||
|                         builder.append("  "sv); | ||||
|                     auto& layout_text = static_cast<Layout::TextNode const&>(fragment.layout_node()); | ||||
|                     auto fragment_text = layout_text.text_for_rendering().substring(fragment.start(), fragment.length()); | ||||
|                     auto fragment_text = MUST(layout_text.text_for_rendering().substring_from_byte_offset(fragment.start(), fragment.length())); | ||||
|                     builder.appendff("      \"{}\"\n", fragment_text); | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -306,7 +306,7 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) | |||
|                     next_width = iterator.next_non_whitespace_sequence_width(); | ||||
|                 } else { | ||||
|                     // In whitespace-preserving contexts (white-space: pre*), we have to check manually.
 | ||||
|                     auto view = text_node.text_for_rendering().substring_view(item.offset_in_node, item.length_in_node); | ||||
|                     auto view = text_node.text_for_rendering().bytes_as_string_view().substring_view(item.offset_in_node, item.length_in_node); | ||||
|                     is_whitespace = view.is_whitespace(); | ||||
|                     if (is_whitespace) | ||||
|                         next_width = iterator.next_non_whitespace_sequence_width(); | ||||
|  |  | |||
|  | @ -148,7 +148,7 @@ CSSPixels InlineLevelIterator::next_non_whitespace_sequence_width() | |||
|             if (next_item.is_collapsible_whitespace) | ||||
|                 break; | ||||
|             auto& next_text_node = verify_cast<Layout::TextNode>(*(next_item.node)); | ||||
|             auto next_view = next_text_node.text_for_rendering().substring_view(next_item.offset_in_node, next_item.length_in_node); | ||||
|             auto next_view = next_text_node.text_for_rendering().bytes_as_string_view().substring_view(next_item.offset_in_node, next_item.length_in_node); | ||||
|             if (next_view.is_whitespace()) | ||||
|                 break; | ||||
|         } | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ StringView LineBoxFragment::text() const | |||
| { | ||||
|     if (!is<TextNode>(layout_node())) | ||||
|         return {}; | ||||
|     return verify_cast<TextNode>(layout_node()).text_for_rendering().substring_view(m_start, m_length); | ||||
|     return verify_cast<TextNode>(layout_node()).text_for_rendering().bytes_as_string_view().substring_view(m_start, m_length); | ||||
| } | ||||
| 
 | ||||
| CSSPixelRect const LineBoxFragment::absolute_rect() const | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ static bool is_all_whitespace(StringView string) | |||
| } | ||||
| 
 | ||||
| // https://w3c.github.io/mathml-core/#new-text-transform-values
 | ||||
| static DeprecatedString apply_math_auto_text_transform(DeprecatedString const& string) | ||||
| static String apply_math_auto_text_transform(String const& string) | ||||
| { | ||||
| 
 | ||||
|     // https://w3c.github.io/mathml-core/#italic-mappings
 | ||||
|  | @ -268,27 +268,27 @@ static DeprecatedString apply_math_auto_text_transform(DeprecatedString const& s | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     StringBuilder builder(string.length()); | ||||
|     StringBuilder builder(string.bytes().size()); | ||||
| 
 | ||||
|     for (auto code_point : Utf8View(string)) | ||||
|     for (auto code_point : string.code_points()) | ||||
|         builder.append_code_point(map_code_point_to_italic(code_point)); | ||||
| 
 | ||||
|     return builder.to_deprecated_string(); | ||||
|     return MUST(builder.to_string()); | ||||
| } | ||||
| 
 | ||||
| static ErrorOr<DeprecatedString> apply_text_transform(DeprecatedString const& string, CSS::TextTransform text_transform) | ||||
| static ErrorOr<String> apply_text_transform(String const& string, CSS::TextTransform text_transform) | ||||
| { | ||||
|     switch (text_transform) { | ||||
|     case CSS::TextTransform::Uppercase: | ||||
|         return Unicode::to_unicode_uppercase_full(string); | ||||
|         return string.to_uppercase(); | ||||
|     case CSS::TextTransform::Lowercase: | ||||
|         return Unicode::to_unicode_lowercase_full(string); | ||||
|         return string.to_lowercase(); | ||||
|     case CSS::TextTransform::None: | ||||
|         return string; | ||||
|     case CSS::TextTransform::MathAuto: | ||||
|         return apply_math_auto_text_transform(string); | ||||
|     case CSS::TextTransform::Capitalize: { | ||||
|         return TRY(Unicode::to_unicode_titlecase_full(string, {}, Unicode::TrailingCodePointTransformation::PreserveExisting)).to_deprecated_string(); | ||||
|         return string.to_titlecase({}, TrailingCodePointTransformation::PreserveExisting); | ||||
|     } | ||||
|     case CSS::TextTransform::FullSizeKana: | ||||
|     case CSS::TextTransform::FullWidth: | ||||
|  | @ -304,7 +304,7 @@ void TextNode::invalidate_text_for_rendering() | |||
|     m_text_for_rendering = {}; | ||||
| } | ||||
| 
 | ||||
| DeprecatedString const& TextNode::text_for_rendering() const | ||||
| String const& TextNode::text_for_rendering() const | ||||
| { | ||||
|     if (!m_text_for_rendering.has_value()) | ||||
|         const_cast<TextNode*>(this)->compute_text_for_rendering(); | ||||
|  | @ -330,10 +330,12 @@ void TextNode::compute_text_for_rendering() | |||
|     if (dom_node().is_editable() && !dom_node().is_uninteresting_whitespace_node()) | ||||
|         collapse = false; | ||||
| 
 | ||||
|     auto data = apply_text_transform(dom_node().data().to_deprecated_string(), computed_values().text_transform()).release_value_but_fixme_should_propagate_errors(); | ||||
|     auto data = apply_text_transform(dom_node().data(), computed_values().text_transform()).release_value_but_fixme_should_propagate_errors(); | ||||
| 
 | ||||
|     auto data_view = data.bytes_as_string_view(); | ||||
| 
 | ||||
|     if (dom_node().is_password_input()) { | ||||
|         m_text_for_rendering = DeprecatedString::repeated('*', data.length()); | ||||
|         m_text_for_rendering = MUST(String::repeated('*', data_view.length())); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -343,9 +345,9 @@ void TextNode::compute_text_for_rendering() | |||
|     } | ||||
| 
 | ||||
|     // NOTE: A couple fast returns to avoid unnecessarily allocating a StringBuilder.
 | ||||
|     if (data.length() == 1) { | ||||
|         if (is_ascii_space(data[0])) { | ||||
|             static DeprecatedString s_single_space_string = " "; | ||||
|     if (data_view.length() == 1) { | ||||
|         if (is_ascii_space(data_view[0])) { | ||||
|             static String s_single_space_string = " "_string; | ||||
|             m_text_for_rendering = s_single_space_string; | ||||
|         } else { | ||||
|             m_text_for_rendering = data; | ||||
|  | @ -354,7 +356,7 @@ void TextNode::compute_text_for_rendering() | |||
|     } | ||||
| 
 | ||||
|     bool contains_space = false; | ||||
|     for (auto& c : data) { | ||||
|     for (auto c : data_view) { | ||||
|         if (is_ascii_space(c)) { | ||||
|             contains_space = true; | ||||
|             break; | ||||
|  | @ -365,26 +367,26 @@ void TextNode::compute_text_for_rendering() | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     StringBuilder builder(data.length()); | ||||
|     StringBuilder builder(data_view.length()); | ||||
|     size_t index = 0; | ||||
| 
 | ||||
|     auto skip_over_whitespace = [&index, &data] { | ||||
|         while (index < data.length() && is_ascii_space(data[index])) | ||||
|     auto skip_over_whitespace = [&index, &data_view] { | ||||
|         while (index < data_view.length() && is_ascii_space(data_view[index])) | ||||
|             ++index; | ||||
|     }; | ||||
| 
 | ||||
|     while (index < data.length()) { | ||||
|         if (is_ascii_space(data[index])) { | ||||
|     while (index < data_view.length()) { | ||||
|         if (is_ascii_space(data_view[index])) { | ||||
|             builder.append(' '); | ||||
|             ++index; | ||||
|             skip_over_whitespace(); | ||||
|         } else { | ||||
|             builder.append(data[index]); | ||||
|             builder.append(data_view[index]); | ||||
|             ++index; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     m_text_for_rendering = builder.to_deprecated_string(); | ||||
|     m_text_for_rendering = MUST(builder.to_string()); | ||||
| } | ||||
| 
 | ||||
| TextNode::ChunkIterator::ChunkIterator(StringView text, bool wrap_lines, bool respect_linebreaks) | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ public: | |||
| 
 | ||||
|     const DOM::Text& dom_node() const { return static_cast<const DOM::Text&>(*Node::dom_node()); } | ||||
| 
 | ||||
|     DeprecatedString const& text_for_rendering() const; | ||||
|     String const& text_for_rendering() const; | ||||
| 
 | ||||
|     struct Chunk { | ||||
|         Utf8View view; | ||||
|  | @ -55,7 +55,7 @@ public: | |||
| private: | ||||
|     virtual bool is_text_node() const final { return true; } | ||||
| 
 | ||||
|     Optional<DeprecatedString> m_text_for_rendering; | ||||
|     Optional<String> m_text_for_rendering; | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
|  |  | |||
|  | @ -234,13 +234,13 @@ ErrorOr<void> TreeBuilder::create_pseudo_element_if_needed(DOM::Element& element | |||
| 
 | ||||
| static bool is_ignorable_whitespace(Layout::Node const& node) | ||||
| { | ||||
|     if (node.is_text_node() && static_cast<TextNode const&>(node).text_for_rendering().is_whitespace()) | ||||
|     if (node.is_text_node() && static_cast<TextNode const&>(node).text_for_rendering().bytes_as_string_view().is_whitespace()) | ||||
|         return true; | ||||
| 
 | ||||
|     if (node.is_anonymous() && node.is_block_container() && static_cast<BlockContainer const&>(node).children_are_inline()) { | ||||
|         bool contains_only_white_space = true; | ||||
|         node.for_each_in_inclusive_subtree_of_type<TextNode>([&contains_only_white_space](auto& text_node) { | ||||
|             if (!text_node.text_for_rendering().is_whitespace()) { | ||||
|             if (!text_node.text_for_rendering().bytes_as_string_view().is_whitespace()) { | ||||
|                 contains_only_white_space = false; | ||||
|                 return IterationDecision::Break; | ||||
|             } | ||||
|  |  | |||
|  | @ -615,7 +615,7 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint position, CSSPixelPoint scre | |||
|                 // Start from one before the index position to prevent selecting only spaces between words, caused by the addition below.
 | ||||
|                 // This also helps us dealing with cases where index is equal to the string length.
 | ||||
|                 for (int i = result->index_in_node - 1; i >= 0; --i) { | ||||
|                     if (is_ascii_space(text_for_rendering[i])) { | ||||
|                     if (is_ascii_space(text_for_rendering.bytes_as_string_view()[i])) { | ||||
|                         // Don't include the space in the selection
 | ||||
|                         return i + 1; | ||||
|                     } | ||||
|  | @ -624,11 +624,11 @@ bool EventHandler::handle_doubleclick(CSSPixelPoint position, CSSPixelPoint scre | |||
|             }(); | ||||
| 
 | ||||
|             int first_word_break_after = [&] { | ||||
|                 for (size_t i = result->index_in_node; i < text_for_rendering.length(); ++i) { | ||||
|                     if (is_ascii_space(text_for_rendering[i])) | ||||
|                 for (size_t i = result->index_in_node; i < text_for_rendering.bytes().size(); ++i) { | ||||
|                     if (is_ascii_space(text_for_rendering.bytes_as_string_view()[i])) | ||||
|                         return i; | ||||
|                 } | ||||
|                 return text_for_rendering.length(); | ||||
|                 return text_for_rendering.bytes().size(); | ||||
|             }(); | ||||
| 
 | ||||
|             auto& realm = node->document().realm(); | ||||
|  |  | |||
|  | @ -645,7 +645,7 @@ static void paint_text_fragment(PaintContext& context, Layout::TextNode const& t | |||
|         auto text = text_node.text_for_rendering(); | ||||
| 
 | ||||
|         DevicePixelPoint baseline_start { fragment_absolute_device_rect.x(), fragment_absolute_device_rect.y() + context.rounded_device_pixels(fragment.baseline()) }; | ||||
|         Utf8View view { text.substring_view(fragment.start(), fragment.length()) }; | ||||
|         Utf8View view { text.code_points().substring_view(fragment.start(), fragment.length()) }; | ||||
| 
 | ||||
|         auto& scaled_font = fragment.layout_node().scaled_font(context); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Shannon Booth
						Shannon Booth