Title: [156536] trunk
Revision
156536
Author
[email protected]
Date
2013-09-27 05:47:52 -0700 (Fri, 27 Sep 2013)

Log Message

Unexpected word wrapping for wrapped content then raw content.
https://bugs.webkit.org/show_bug.cgi?id=121130

Reviewed by Darin Adler.

When deciding whether a line is considered empty, we need to check if the current
object is fully responsible for the currently uncommitted width. It helps differentiating
<span></span><span>abcd</span> from <span>a</span><span>bcd</span>, where in the first
case when we hit the second <span> the line is still considered empty, as opposed to the
second example.
This patch introduces a map to keep track of the uncommitted widths.

Source/WebCore:

Test: fast/css/unexpected-word-wrapping-with-non-empty-spans.html

* rendering/LineWidth.cpp:
(WebCore::LineWidth::uncommittedWidthForObject):
(WebCore::LineWidth::addUncommittedWidth):
* rendering/LineWidth.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::LineBreaker::nextSegmentBreak):

LayoutTests:

* fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html: Added.
* fast/css/unexpected-word-wrapping-with-non-empty-spans.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (156535 => 156536)


--- trunk/LayoutTests/ChangeLog	2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/LayoutTests/ChangeLog	2013-09-27 12:47:52 UTC (rev 156536)
@@ -1,3 +1,20 @@
+2013-09-27  Zalan Bujtas  <[email protected]>
+
+        Unexpected word wrapping for wrapped content then raw content.
+        https://bugs.webkit.org/show_bug.cgi?id=121130
+
+        Reviewed by Darin Adler.
+
+        When deciding whether a line is considered empty, we need to check if the current
+        object is fully responsible for the currently uncommitted width. It helps differentiating
+        <span></span><span>abcd</span> from <span>a</span><span>bcd</span>, where in the first
+        case when we hit the second <span> the line is still considered empty, as opposed to the
+        second example.
+        This patch introduces a map to keep track of the uncommitted widths.
+
+        * fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html: Added.
+        * fast/css/unexpected-word-wrapping-with-non-empty-spans.html: Added.
+
 2013-09-27  Mario Sanchez Prada  <[email protected]>
 
         [ATK] Protect entry points in the ATK wrapper against outdated render trees

Added: trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html (0 => 156536)


--- trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans-expected.html	2013-09-27 12:47:52 UTC (rev 156536)
@@ -0,0 +1,23 @@
+<html>
+<head>
+  <style>
+    div {
+      border: 1px solid red;
+      width: 16px;
+      word-wrap: break-word;
+    }
+  </style>
+</head>
+<body>
+<p>This tests if non-empty spans changes word wrapping.</p>
+<div>
+    1234
+</div>
+<div>
+    1234
+</div>
+<div>
+    12345678
+    12345678
+</div>
+</html>

Added: trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans.html (0 => 156536)


--- trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/unexpected-word-wrapping-with-non-empty-spans.html	2013-09-27 12:47:52 UTC (rev 156536)
@@ -0,0 +1,23 @@
+<html>
+<head>
+  <style>
+    div {
+      border: 1px solid red;
+      width: 16px;
+      word-wrap: break-word;
+    }
+  </style>
+</head>
+<body>
+<p>This tests if non-empty spans changes word wrapping.</p>
+<div>
+    <span>123</span><span></span><span>4</span>
+</div>
+<div>
+    <span></span><span>123</span><span>4</span>
+</div>
+<div>
+    12345678
+    <span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span>
+</div>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (156535 => 156536)


--- trunk/Source/WebCore/ChangeLog	2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/ChangeLog	2013-09-27 12:47:52 UTC (rev 156536)
@@ -1,3 +1,26 @@
+2013-09-27  Zalan Bujtas  <[email protected]>
+
+        Unexpected word wrapping for wrapped content then raw content.
+        https://bugs.webkit.org/show_bug.cgi?id=121130
+
+        Reviewed by Darin Adler.
+
+        When deciding whether a line is considered empty, we need to check if the current
+        object is fully responsible for the currently uncommitted width. It helps differentiating
+        <span></span><span>abcd</span> from <span>a</span><span>bcd</span>, where in the first
+        case when we hit the second <span> the line is still considered empty, as opposed to the
+        second example.
+        This patch introduces a map to keep track of the uncommitted widths.
+
+        Test: fast/css/unexpected-word-wrapping-with-non-empty-spans.html
+
+        * rendering/LineWidth.cpp:
+        (WebCore::LineWidth::uncommittedWidthForObject):
+        (WebCore::LineWidth::addUncommittedWidth):
+        * rendering/LineWidth.h:
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::LineBreaker::nextSegmentBreak):
+
 2013-09-27  Mario Sanchez Prada  <[email protected]>
 
         [ATK] Protect entry points in the ATK wrapper against outdated render trees

Modified: trunk/Source/WebCore/rendering/LineWidth.cpp (156535 => 156536)


--- trunk/Source/WebCore/rendering/LineWidth.cpp	2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/rendering/LineWidth.cpp	2013-09-27 12:47:52 UTC (rev 156536)
@@ -150,6 +150,23 @@
     computeAvailableWidthFromLeftAndRight();
 }
 
+float LineWidth::uncommittedWidthForObject(const RenderObject& object) const
+{
+    auto result = m_uncommittedWidthMap.find(&object);
+    if (result != m_uncommittedWidthMap.end())
+        return result->value;
+    return -1;
+}
+
+void LineWidth::addUncommittedWidth(float delta, const RenderObject& current)
+{
+    m_uncommittedWidth += delta;
+
+    auto result = m_uncommittedWidthMap.add(&current, delta);
+    if (!result.isNewEntry)
+        result.iterator->value += delta;
+}
+
 void LineWidth::commit()
 {
     m_committedWidth += m_uncommittedWidth;

Modified: trunk/Source/WebCore/rendering/LineWidth.h (156535 => 156536)


--- trunk/Source/WebCore/rendering/LineWidth.h	2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/rendering/LineWidth.h	2013-09-27 12:47:52 UTC (rev 156536)
@@ -31,6 +31,7 @@
 #define LineWidth_h
 
 #include "LayoutUnit.h"
+#include <wtf/HashMap.h>
 
 namespace WebCore {
 
@@ -53,12 +54,13 @@
     float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
     // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
     float uncommittedWidth() const { return m_uncommittedWidth; }
+    float uncommittedWidthForObject(const RenderObject&) const;
     float committedWidth() const { return m_committedWidth; }
     float availableWidth() const { return m_availableWidth; }
 
     void updateAvailableWidth(LayoutUnit minimumHeight = 0);
     void shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject*);
-    void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
+    void addUncommittedWidth(float delta, const RenderObject&);
     void commit();
     void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
     void fitBelowFloats();
@@ -88,6 +90,7 @@
 #endif
     bool m_isFirstLine;
     IndentTextOrNot m_shouldIndentText;
+    HashMap<const RenderObject*, float> m_uncommittedWidthMap;
 };
 
 }

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (156535 => 156536)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2013-09-27 12:16:23 UTC (rev 156535)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2013-09-27 12:47:52 UTC (rev 156536)
@@ -2789,7 +2789,7 @@
                 trailingObjects.appendBoxIfNeeded(box);
             } else
                 m_positionedObjects.append(box);
-            width.addUncommittedWidth(inlineLogicalWidth(current.m_obj));
+            width.addUncommittedWidth(inlineLogicalWidth(current.m_obj), *current.m_obj);
             // Reset prior line break context characters.
             renderTextInfo.m_lineBreakIterator.resetPriorContext();
         } else if (current.m_obj->isFloating()) {
@@ -2840,7 +2840,7 @@
                 }
             }
 
-            width.addUncommittedWidth(inlineLogicalWidth(current.m_obj) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
+            width.addUncommittedWidth(inlineLogicalWidth(current.m_obj) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox), *current.m_obj);
         } else if (current.m_obj->isReplaced()) {
             RenderBox* replacedBox = toRenderBox(current.m_obj);
 
@@ -2872,9 +2872,9 @@
                     ignoringSpaces = true;
                 }
                 if (toRenderListMarker(*current.m_obj).isInside())
-                    width.addUncommittedWidth(replacedLogicalWidth);
+                    width.addUncommittedWidth(replacedLogicalWidth, *current.m_obj);
             } else
-                width.addUncommittedWidth(replacedLogicalWidth);
+                width.addUncommittedWidth(replacedLogicalWidth, *current.m_obj);
             if (current.m_obj->isRubyRun())
                 width.applyOverhang(toRenderRubyRun(current.m_obj), last, next);
             // Update prior line break context characters, using U+FFFD (OBJECT REPLACEMENT CHARACTER) for replaced element.
@@ -2962,7 +2962,7 @@
 
                 if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphens() != HyphensNone) {
                     hyphenWidth = measureHyphenWidth(t, f, &fallbackFonts);
-                    width.addUncommittedWidth(hyphenWidth);
+                    width.addUncommittedWidth(hyphenWidth, *current.m_obj);
                 }
 
                 bool applyWordSpacing = false;
@@ -3016,13 +3016,13 @@
 
                     wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeasurement;
                     additionalTempWidth += lastSpaceWordSpacing;
-                    width.addUncommittedWidth(additionalTempWidth);
+                    width.addUncommittedWidth(additionalTempWidth, *current.m_obj);
 
                     if (collapseWhiteSpace && previousCharacterIsSpace && currentCharacterIsSpace && additionalTempWidth)
                         width.setTrailingWhitespaceWidth(additionalTempWidth);
 
                     if (!appliedStartWidth) {
-                        width.addUncommittedWidth(inlineLogicalWidth(current.m_obj, true, false));
+                        width.addUncommittedWidth(inlineLogicalWidth(current.m_obj, true, false), *current.m_obj);
                         appliedStartWidth = true;
                     }
 
@@ -3078,10 +3078,10 @@
                                 goto end;
                         } else {
                             if (!betweenWords || (midWordBreak && !autoWrap))
-                                width.addUncommittedWidth(-additionalTempWidth);
+                                width.addUncommittedWidth(-additionalTempWidth, *current.m_obj);
                             if (hyphenWidth) {
                                 // Subtract the width of the soft hyphen out since we fit on a line.
-                                width.addUncommittedWidth(-hyphenWidth);
+                                width.addUncommittedWidth(-hyphenWidth, *current.m_obj);
                                 hyphenWidth = 0;
                             }
                         }
@@ -3193,7 +3193,7 @@
             additionalTempWidth += lastSpaceWordSpacing;
 
             float inlineLogicalTempWidth = inlineLogicalWidth(current.m_obj, !appliedStartWidth, includeEndWidth);
-            width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth);
+            width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth, *current.m_obj);
 
             if (wordMeasurement.fallbackFonts.isEmpty() && !fallbackFonts.isEmpty())
                 wordMeasurement.fallbackFonts.swap(fallbackFonts);
@@ -3283,7 +3283,7 @@
             // make sure we consume at least one char/object.
             if (lBreak == resolver.position())
                 lBreak.increment();
-        } else if (!width.committedWidth() && (!current.m_obj || !current.m_obj->isBR()) && !current.m_pos) {
+        } else if (!current.m_pos && !width.committedWidth() && current.m_obj && width.uncommittedWidthForObject(*current.m_obj) == width.uncommittedWidth()) {
             // Do not push the current object to the next line, when this line has some content, but it is still considered empty.
             // Empty inline elements like <span></span> can produce such lines and now we just ignore these break opportunities
             // at the start of a line, if no width has been committed yet.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to