Modified: trunk/LayoutTests/ChangeLog (152312 => 152313)
--- trunk/LayoutTests/ChangeLog 2013-07-02 19:30:20 UTC (rev 152312)
+++ trunk/LayoutTests/ChangeLog 2013-07-02 19:30:32 UTC (rev 152313)
@@ -1,3 +1,13 @@
+2013-06-26 Robert Hogan <[email protected]>
+
+ empty inlines should not affect line-wrapping
+ https://bugs.webkit.org/show_bug.cgi?id=25638
+
+ Reviewed by David Hyatt.
+
+ * fast/text/whitespace/inline-whitespace-wrapping-11-expected.html: Added.
+ * fast/text/whitespace/inline-whitespace-wrapping-11.html: Added.
+
2013-07-02 Tim Horton <[email protected]>
constrainScrollPositionForOverhang needs to handle scrollOrigin correctly
Added: trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11-expected.html (0 => 152313)
--- trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11-expected.html 2013-07-02 19:30:32 UTC (rev 152313)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+div {
+ font: 20px/1 Ahem;
+ width: 1em;
+ color: green;
+}
+
+</style>
+webkit.org/b/25638: This test passes if there is a green rectangle below. It tests that we don't
+break on an empty inline span in the middle of a word.<br>
+<div>word</div>
+This test passes if there is a green square below. It tests that we
+break on the space after an empty inline span.<br>
+<div>wo rd</div>
Property changes on: trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11-expected.html
___________________________________________________________________
Added: trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11.html (0 => 152313)
--- trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11.html 2013-07-02 19:30:32 UTC (rev 152313)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+div {
+ font: 20px/1 Ahem;
+ width: 1em;
+ color: green;
+}
+
+</style>
+webkit.org/b/25638: This test passes if there is a green rectangle below. It tests that we don't
+break on an empty inline span in the middle of a word.<br>
+<div>wo<span></span>rd</div>
+This test passes if there is a green square below. It tests that we
+break on the space after an empty inline span.<br>
+<div>wo<span></span> rd</div>
Property changes on: trunk/LayoutTests/fast/text/whitespace/inline-whitespace-wrapping-11.html
___________________________________________________________________
Modified: trunk/Source/WebCore/ChangeLog (152312 => 152313)
--- trunk/Source/WebCore/ChangeLog 2013-07-02 19:30:20 UTC (rev 152312)
+++ trunk/Source/WebCore/ChangeLog 2013-07-02 19:30:32 UTC (rev 152313)
@@ -1,3 +1,20 @@
+2013-06-26 Robert Hogan <[email protected]>
+
+ empty inlines should not affect line-wrapping
+ https://bugs.webkit.org/show_bug.cgi?id=25638
+
+ Reviewed by David Hyatt.
+
+ Don't break on empty inlines if we're in the middle of a word. I took this opportunity to
+ refactor the series of checks we perform to establish if we can break at the current position.
+
+ Test: fast/text/whitespace/inline-whitespace-wrapping-11.html
+
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::textBeginsWithBreakablePosition):
+ (WebCore::canBreakAtThisPosition):
+ (WebCore::RenderBlock::LineBreaker::nextSegmentBreak):
+
2013-07-02 Jae Hyun Park <[email protected]>
Implement CoordinatedSurface for Threaded Coordinated Graphics
Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (152312 => 152313)
--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2013-07-02 19:30:20 UTC (rev 152312)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2013-07-02 19:30:32 UTC (rev 152313)
@@ -2869,6 +2869,54 @@
lBreak.moveTo(object, offset, nextBreak);
}
+static bool textBeginsWithBreakablePosition(RenderObject* next)
+{
+ ASSERT(next->isText());
+ RenderText* nextText = toRenderText(next);
+ if (nextText->isWordBreak())
+ return true;
+ if (!nextText->textLength())
+ return false;
+ UChar c = nextText->characterAt(0);
+ return c == ' ' || c == '\t' || (c == '\n' && !nextText->preservesNewline());
+}
+
+static bool canBreakAtThisPosition(bool autoWrap, LineWidth& width, InlineIterator& lBreak, RenderObject* next, const InlineIterator& current, EWhiteSpace currWS, bool currentCharacterIsSpace, bool autoWrapWasEverTrueOnLine)
+{
+ // If we are no-wrap and have found a line-breaking opportunity already then we should take it.
+ if (width.committedWidth() && !width.fitsOnLine(currentCharacterIsSpace) && currWS == NOWRAP)
+ return true;
+
+ // Avoid breaking before empty inlines.
+ if (next && isEmptyInline(next))
+ return false;
+
+ // Return early if we autowrap and the current character is a space as we will always want to break at such a position.
+ if (autoWrap && currentCharacterIsSpace)
+ return true;
+
+ bool nextIsText = (next && (current.m_obj->isText() || isEmptyInline(current.m_obj)) && next->isText() && !next->isBR() && (autoWrap || next->style()->autoWrap()));
+ if (!nextIsText)
+ return autoWrap;
+
+ bool canBreakHere = !currentCharacterIsSpace && textBeginsWithBreakablePosition(next);
+
+ // See if attempting to fit below floats creates more available width on the line.
+ if (!width.fitsOnLine() && !width.committedWidth())
+ width.fitBelowFloats();
+
+ bool canPlaceOnLine = width.fitsOnLine() || !autoWrapWasEverTrueOnLine;
+
+ // If we are an empty inline in the middle of a word and don't fit on the line then clear any line break we have and find
+ // one in the following text instead.
+ if (!canPlaceOnLine && !canBreakHere && isEmptyInline(current.m_obj))
+ lBreak.clear();
+ else if (canPlaceOnLine && canBreakHere)
+ commitLineBreakAtCurrentWidth(width, lBreak, next);
+
+ return canBreakHere;
+}
+
InlineIterator RenderBlock::LineBreaker::nextSegmentBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
{
reset();
@@ -3408,30 +3456,8 @@
} else
ASSERT_NOT_REACHED();
- bool checkForBreak = autoWrap;
- if (width.committedWidth() && !width.fitsOnLine(currentCharacterIsSpace) && lBreak.m_obj && currWS == NOWRAP)
- checkForBreak = true;
- else if (next && current.m_obj->isText() && next->isText() && !next->isBR() && (autoWrap || next->style()->autoWrap())) {
- if (autoWrap && currentCharacterIsSpace)
- checkForBreak = true;
- else {
- RenderText* nextText = toRenderText(next);
- if (nextText->textLength()) {
- UChar c = nextText->characterAt(0);
- checkForBreak = !currentCharacterIsSpace && (c == ' ' || c == '\t' || (c == '\n' && !next->preservesNewline()));
- } else if (nextText->isWordBreak())
- checkForBreak = true;
-
- if (!width.fitsOnLine() && !width.committedWidth())
- width.fitBelowFloats();
-
- bool canPlaceOnLine = width.fitsOnLine() || !autoWrapWasEverTrueOnLine;
- if (canPlaceOnLine && checkForBreak)
- commitLineBreakAtCurrentWidth(width, lBreak, next);
- }
- }
-
- if (checkForBreak && !width.fitsOnLine(ignoringSpaces)) {
+ bool canBreakHere = canBreakAtThisPosition(autoWrap, width, lBreak, next, current, currWS, currentCharacterIsSpace, autoWrapWasEverTrueOnLine);
+ if (canBreakHere && !width.fitsOnLine(ignoringSpaces)) {
// if we have floats, try to get below them.
if (currentCharacterIsSpace && !ignoringSpaces && currentStyle->collapseWhiteSpace())
trailingObjects.clear();