summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-10-09 16:29:23 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-10-09 16:29:35 +0200
commit2ac190dc5fd2d22ced31c18fc123c99ee9e7577c (patch)
treea4f02ff489ab2eddc2805a425ee87c3fd4b6e382 /Libraries
parentb4389ca4b00e19f9399031bf47b09397ef1e50fa (diff)
downloadserenity-2ac190dc5fd2d22ced31c18fc123c99ee9e7577c.zip
LibHTML: Collapse whitespace in LayoutText unless white-space: pre;
Before breaking the Text node contents into words, collapse all of the whitespace into single space (' ') characters. This fixes broken rendering of paragraphs with newlines in them. :^)
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibHTML/Layout/LayoutText.cpp24
-rw-r--r--Libraries/LibHTML/Layout/LayoutText.h2
2 files changed, 22 insertions, 4 deletions
diff --git a/Libraries/LibHTML/Layout/LayoutText.cpp b/Libraries/LibHTML/Layout/LayoutText.cpp
index 581760d11c..ff1c072010 100644
--- a/Libraries/LibHTML/Layout/LayoutText.cpp
+++ b/Libraries/LibHTML/Layout/LayoutText.cpp
@@ -48,13 +48,13 @@ void LayoutText::render_fragment(RenderingContext& context, const LineBoxFragmen
if (is_underline)
painter.draw_line(fragment.rect().bottom_left().translated(0, -1), fragment.rect().bottom_right().translated(0, -1), color);
- painter.draw_text(fragment.rect(), node().data().substring_view(fragment.start(), fragment.length()), TextAlignment::TopLeft, color);
+ painter.draw_text(fragment.rect(), m_text_for_rendering.substring_view(fragment.start(), fragment.length()), TextAlignment::TopLeft, color);
}
template<typename Callback>
void LayoutText::for_each_word(Callback callback) const
{
- Utf8View view(node().data());
+ Utf8View view(m_text_for_rendering);
if (view.is_empty())
return;
@@ -90,7 +90,7 @@ void LayoutText::for_each_word(Callback callback) const
template<typename Callback>
void LayoutText::for_each_source_line(Callback callback) const
{
- Utf8View view(node().data());
+ Utf8View view(m_text_for_rendering);
if (view.is_empty())
return;
@@ -133,6 +133,7 @@ void LayoutText::split_into_lines(LayoutBlock& container)
bool is_preformatted = style().string_or_fallback(CSS::PropertyID::WhiteSpace, "normal") == "pre";
if (is_preformatted) {
+ m_text_for_rendering = node().data();
for_each_source_line([&](const Utf8View& view, int start, int length) {
line_boxes.last().add_fragment(*this, start, length, font.width(view), line_height);
line_boxes.append(LineBox());
@@ -140,6 +141,21 @@ void LayoutText::split_into_lines(LayoutBlock& container)
return;
}
+ // Collapse whitespace into single spaces
+ auto& raw_text = node().data();
+ StringBuilder builder(raw_text.length());
+ for (int i = 0; i < raw_text.length(); ++i) {
+ if (!isspace(raw_text[i])) {
+ builder.append(raw_text[i]);
+ } else {
+ builder.append(' ');
+ while (i < raw_text.length() && isspace(raw_text[i]))
+ ++i;
+ --i;
+ }
+ }
+ m_text_for_rendering = builder.to_string();
+
struct Word {
Utf8View view;
int start;
@@ -170,7 +186,7 @@ void LayoutText::split_into_lines(LayoutBlock& container)
if (is_whitespace && line_boxes.last().fragments().is_empty())
continue;
- line_boxes.last().add_fragment(*this, word.start, word.length, word_width, line_height);
+ line_boxes.last().add_fragment(*this, word.start, is_whitespace ? 1 : word.length, word_width, line_height);
available_width -= word_width;
if (available_width < 0) {
diff --git a/Libraries/LibHTML/Layout/LayoutText.h b/Libraries/LibHTML/Layout/LayoutText.h
index 9b70ecdc4c..afa3a808c7 100644
--- a/Libraries/LibHTML/Layout/LayoutText.h
+++ b/Libraries/LibHTML/Layout/LayoutText.h
@@ -28,4 +28,6 @@ private:
void for_each_word(Callback) const;
template<typename Callback>
void for_each_source_line(Callback) const;
+
+ String m_text_for_rendering;
};