Diff
Modified: trunk/Source/WebCore/ChangeLog (253467 => 253468)
--- trunk/Source/WebCore/ChangeLog 2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/ChangeLog 2019-12-13 13:47:50 UTC (rev 253468)
@@ -1,3 +1,23 @@
+2019-12-13 Zalan Bujtas <[email protected]>
+
+ [LFC][IFC] Fix fast/text/simple-line-with-multiple-renderers.html
+ https://bugs.webkit.org/show_bug.cgi?id=205193
+ <rdar://problem/57900709>
+
+ Reviewed by Antti Koivisto.
+
+ Use LazyLineBreakIterator to find out if 2 (visually)adjacent non-whitespace inline items are
+ on a soft breaking opportunity.
+
+ * layout/inlineformatting/InlineLineBreaker.cpp:
+ (WebCore::Layout::endsWithBreakingOpportunity):
+ (WebCore::Layout::LineBreaker::Content::isAtContentBoundary):
+ * layout/inlineformatting/InlineTextItem.cpp:
+ (WebCore::Layout::moveToNextBreakablePosition):
+ * layout/inlineformatting/text/TextUtil.cpp:
+ (WebCore::Layout::TextUtil::findNextBreakablePosition):
+ * layout/inlineformatting/text/TextUtil.h:
+
2019-12-13 Carlos Garcia Campos <[email protected]>
Uninitialized variables in RenderLayer
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (253467 => 253468)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp 2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp 2019-12-13 13:47:50 UTC (rev 253468)
@@ -223,6 +223,30 @@
return LeftSide { hyphenLocation, trailingPartialRunWidthWithHyphen, true };
}
+static bool endsWithBreakingOpportunity(const InlineTextItem& previousTextItem, const InlineTextItem& nextInlineTextItem)
+{
+ ASSERT(!previousTextItem.isWhitespace());
+ ASSERT(!nextInlineTextItem.isWhitespace());
+ // When both these non-whitespace runs belong to the same layout box, it's guaranteed that
+ // they are split at a soft breaking opportunity. See InlineTextItem::moveToNextBreakablePosition.
+ if (&previousTextItem.layoutBox() == &nextInlineTextItem.layoutBox())
+ return true;
+ // Now we need to collect at least 3 adjacent characters to be able to make a descision whether the previous text item ends with breaking opportunity.
+ // [ex-][ample] <- second to last[x] last[-] current[a]
+ // We need at least 1 character in the current inline text item and 2 more from previous inline items.
+ auto previousContent = previousTextItem.layoutBox().textContext()->content;
+ auto lineBreakIterator = LazyLineBreakIterator { nextInlineTextItem.layoutBox().textContext()->content };
+ auto previousContentLength = previousContent.length();
+ // FIXME: We should look into the entire uncommitted content for more text context.
+ UChar lastCharacter = previousContentLength ? previousContent[previousContentLength - 1] : 0;
+ UChar secondToLastCharacter = previousContentLength > 1 ? previousContent[previousContentLength - 2] : 0;
+ lineBreakIterator.setPriorContext(lastCharacter, secondToLastCharacter);
+ // Now check if we can break right at the inline item boundary.
+ // With the [ex-ample], findNextBreakablePosition should return the startPosition (0).
+ // FIXME: Check if there's a more correct way of finding breaking opportunities.
+ return !TextUtil::findNextBreakablePosition(lineBreakIterator, 0, nextInlineTextItem.style());
+}
+
bool LineBreaker::Content::isAtContentBoundary(const InlineItem& inlineItem, const Content& content)
{
// https://drafts.csswg.org/css-text-3/#line-break-details
@@ -269,12 +293,7 @@
auto& previousInlineTextItem = downcast<InlineTextItem>(*lastUncomittedContent);
if (previousInlineTextItem.isWhitespace())
return true;
- // When both these non-whitespace runs belong to the same layout box, it's guaranteed that
- // they are split at a soft breaking opportunity. See InlineTextItem::moveToNextBreakablePosition.
- if (&inlineItem.layoutBox() == &lastUncomittedContent->layoutBox())
- return true;
- // FIXME: check if <span>text-</span><span>text</span> should be handled here as well.
- return false;
+ return endsWithBreakingOpportunity(previousInlineTextItem, downcast<InlineTextItem>(inlineItem));
}
// <img>text -> the inline box is on a commit boundary.
if (lastUncomittedContent->isBox())
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp (253467 => 253468)
--- trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp 2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp 2019-12-13 13:47:50 UTC (rev 253468)
@@ -28,9 +28,9 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-#include "BreakLines.h"
#include "FontCascade.h"
#include "InlineSoftLineBreakItem.h"
+#include "TextUtil.h"
namespace WebCore {
namespace Layout {
@@ -48,33 +48,12 @@
return nextNonWhiteSpacePosition - startPosition;
}
-static unsigned moveToNextBreakablePosition(unsigned startPosition, LazyLineBreakIterator lineBreakIterator, const RenderStyle& style)
+static unsigned moveToNextBreakablePosition(unsigned startPosition, LazyLineBreakIterator& lineBreakIterator, const RenderStyle& style)
{
- auto findNextBreakablePosition = [&](auto startPosition) {
- auto keepAllWordsForCJK = style.wordBreak() == WordBreak::KeepAll;
- auto breakNBSP = style.autoWrap() && style.nbspMode() == NBSPMode::Space;
-
- if (keepAllWordsForCJK) {
- if (breakNBSP)
- return nextBreakablePositionKeepingAllWords(lineBreakIterator, startPosition);
- return nextBreakablePositionKeepingAllWordsIgnoringNBSP(lineBreakIterator, startPosition);
- }
-
- if (lineBreakIterator.mode() == LineBreakIteratorMode::Default) {
- if (breakNBSP)
- return WebCore::nextBreakablePosition(lineBreakIterator, startPosition);
- return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition);
- }
-
- if (breakNBSP)
- return nextBreakablePositionWithoutShortcut(lineBreakIterator, startPosition);
- return nextBreakablePositionIgnoringNBSPWithoutShortcut(lineBreakIterator, startPosition);
- };
-
auto textLength = lineBreakIterator.stringView().length();
auto startPositionForNextBreakablePosition = startPosition;
while (startPositionForNextBreakablePosition < textLength) {
- auto nextBreakablePosition = findNextBreakablePosition(startPositionForNextBreakablePosition);
+ auto nextBreakablePosition = TextUtil::findNextBreakablePosition(lineBreakIterator, startPositionForNextBreakablePosition, style);
// Oftentimes the next breakable position comes back as the start position (most notably hyphens).
if (nextBreakablePosition != startPosition)
return nextBreakablePosition - startPosition;
Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp (253467 => 253468)
--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp 2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp 2019-12-13 13:47:50 UTC (rev 253468)
@@ -28,6 +28,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "BreakLines.h"
#include "FontCascade.h"
#include "InlineTextItem.h"
#include "RenderStyle.h"
@@ -133,6 +134,28 @@
return whitespace == WhiteSpace::Pre || whitespace == WhiteSpace::PreWrap;
}
+unsigned TextUtil::findNextBreakablePosition(LazyLineBreakIterator& lineBreakIterator, unsigned startPosition, const RenderStyle& style)
+{
+ auto keepAllWordsForCJK = style.wordBreak() == WordBreak::KeepAll;
+ auto breakNBSP = style.autoWrap() && style.nbspMode() == NBSPMode::Space;
+
+ if (keepAllWordsForCJK) {
+ if (breakNBSP)
+ return nextBreakablePositionKeepingAllWords(lineBreakIterator, startPosition);
+ return nextBreakablePositionKeepingAllWordsIgnoringNBSP(lineBreakIterator, startPosition);
+ }
+
+ if (lineBreakIterator.mode() == LineBreakIteratorMode::Default) {
+ if (breakNBSP)
+ return WebCore::nextBreakablePosition(lineBreakIterator, startPosition);
+ return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition);
+ }
+
+ if (breakNBSP)
+ return nextBreakablePositionWithoutShortcut(lineBreakIterator, startPosition);
+ return nextBreakablePositionIgnoringNBSPWithoutShortcut(lineBreakIterator, startPosition);
}
+
}
+}
#endif
Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h (253467 => 253468)
--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h 2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h 2019-12-13 13:47:50 UTC (rev 253468)
@@ -28,6 +28,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "InlineItem.h"
+#include <wtf/text/TextBreakIterator.h>
namespace WebCore {
@@ -46,6 +47,7 @@
};
static SplitData split(const Box&, unsigned startPosition, unsigned length, InlineLayoutUnit textWidth, InlineLayoutUnit availableWidth, InlineLayoutUnit contentLogicalLeft);
static bool shouldPreserveTrailingWhitespace(const RenderStyle&);
+ static unsigned findNextBreakablePosition(LazyLineBreakIterator&, unsigned startPosition, const RenderStyle&);
private:
static InlineLayoutUnit fixedPitchWidth(const StringView&, const RenderStyle&, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft);