Title: [283080] trunk/Source/WebCore
Revision
283080
Author
[email protected]
Date
2021-09-25 08:47:55 -0700 (Sat, 25 Sep 2021)

Log Message

[LFC][IFC] Text measuring is first-line style dependent
https://bugs.webkit.org/show_bug.cgi?id=230796

Reviewed by Antti Koivisto.

First-line style may change the font to be used for measuring the text content.
(This is in preparation for supporting first-line style)

* layout/formattingContexts/inline/InlineContentBreaker.cpp:
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
(WebCore::Layout::InlineContentBreaker::tryBreakingTextRun const):
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::inlineItemWidth const):
* layout/formattingContexts/inline/InlineTextItem.cpp:
(WebCore::Layout::InlineTextItem::createAndAppendTextItems):
* layout/formattingContexts/inline/text/TextUtil.cpp:
(WebCore::Layout::TextUtil::width):
(WebCore::Layout::TextUtil::midWordBreak):
* layout/formattingContexts/inline/text/TextUtil.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (283079 => 283080)


--- trunk/Source/WebCore/ChangeLog	2021-09-25 13:53:27 UTC (rev 283079)
+++ trunk/Source/WebCore/ChangeLog	2021-09-25 15:47:55 UTC (rev 283080)
@@ -1,3 +1,25 @@
+2021-09-25  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Text measuring is first-line style dependent
+        https://bugs.webkit.org/show_bug.cgi?id=230796
+
+        Reviewed by Antti Koivisto.
+
+        First-line style may change the font to be used for measuring the text content.
+        (This is in preparation for supporting first-line style)
+
+        * layout/formattingContexts/inline/InlineContentBreaker.cpp:
+        (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
+        (WebCore::Layout::InlineContentBreaker::tryBreakingTextRun const):
+        * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineBuilder::inlineItemWidth const):
+        * layout/formattingContexts/inline/InlineTextItem.cpp:
+        (WebCore::Layout::InlineTextItem::createAndAppendTextItems):
+        * layout/formattingContexts/inline/text/TextUtil.cpp:
+        (WebCore::Layout::TextUtil::width):
+        (WebCore::Layout::TextUtil::midWordBreak):
+        * layout/formattingContexts/inline/text/TextUtil.h:
+
 2021-09-23  Tim Nguyen  <[email protected]>
 
         Make inert nodes invisible to hit testing

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp (283079 => 283080)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-09-25 13:53:27 UTC (rev 283079)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-09-25 15:47:55 UTC (rev 283080)
@@ -218,7 +218,8 @@
                     return Result { Result::Action::Wrap, IsEndOfLine::Yes };
 
                 auto leadingTextRunIndex = *firstTextRunIndex(continuousContent);
-                auto& inlineTextItem = downcast<InlineTextItem>(continuousContent.runs()[leadingTextRunIndex].inlineItem);
+                auto& leadingTextRun = continuousContent.runs()[leadingTextRunIndex];
+                auto& inlineTextItem = downcast<InlineTextItem>(leadingTextRun.inlineItem);
                 auto firstCodePointLength = [&]() -> size_t {
                     auto textContent = inlineTextItem.inlineTextBox().content();
                     if (textContent.is8Bit())
@@ -232,7 +233,7 @@
                 if (inlineTextItem.length() <= firstCodePointLength)
                     return Result { Result::Action::Keep, IsEndOfLine::Yes };
 
-                auto firstCodePointWidth = TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight);
+                auto firstCodePointWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade, inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight);
                 return Result { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, PartialRun { firstCodePointLength, firstCodePointWidth } } };
             }
             if (trailingContent->overflows && lineStatus.hasContent) {
@@ -473,7 +474,7 @@
                 auto availableWidthExcludingHyphen = *availableWidth - hyphenWidth;
                 if (availableWidthExcludingHyphen <= 0 || !enoughWidthForHyphenation(availableWidthExcludingHyphen, style.fontCascade.pixelSize()))
                     return { };
-                leftSideLength = TextUtil::midWordBreak(inlineTextItem, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length;
+                leftSideLength = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length;
             }
             if (leftSideLength < limitBefore)
                 return { };
@@ -484,7 +485,7 @@
                 return { };
             // hyphenLocation is relative to the start of this InlineItemText.
             ASSERT(inlineTextItem.start() + hyphenLocation < inlineTextItem.end());
-            auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft);
+            auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft);
             return PartialRun { hyphenLocation, trailingPartialRunWidthWithHyphen, hyphenWidth };
         };
         if (auto partialRun = tryBreakingAtHyphenationOpportunity())
@@ -500,7 +501,7 @@
             if (availableSpaceIsInfinite) {
                 // When the run can be split at arbitrary position let's just return the entire run when it is intended to fit on the line.
                 ASSERT(inlineTextItem.length());
-                auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, logicalLeft);
+                auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, logicalLeft);
                 return { inlineTextItem.length(), trailingPartialRunWidth };
             }
             if (!*availableWidth) {
@@ -507,7 +508,7 @@
                 // Fast path for cases when there's no room at all. The content is breakable but we don't have space for it.
                 return { };
             }
-            auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, overflowingRun.logicalWidth, *availableWidth, logicalLeft);
+            auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, *availableWidth, logicalLeft);
             return { midWordBreak.length, midWordBreak.logicalWidth };
         };
         // With arbitrary breaking there's always a valid breaking position (even if it is before the first position).

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp (283079 => 283080)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-09-25 13:53:27 UTC (rev 283079)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-09-25 15:47:55 UTC (rev 283080)
@@ -218,11 +218,12 @@
 {
     if (is<InlineTextItem>(inlineItem)) {
         auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
+        auto& fontCascade = inlineTextItem.layoutBox().style().fontCascade();
         if (auto contentWidth = inlineTextItem.width())
             return *contentWidth;
         if (!inlineTextItem.isWhitespace() || InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem))
-            return TextUtil::width(inlineTextItem, contentLogicalLeft);
-        return TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.start() + 1, contentLogicalLeft);
+            return TextUtil::width(inlineTextItem, fontCascade, contentLogicalLeft);
+        return TextUtil::width(inlineTextItem, fontCascade, inlineTextItem.start(), inlineTextItem.start() + 1, contentLogicalLeft);
     }
 
     if (inlineItem.isLineBreak() || inlineItem.isWordBreakOpportunity())

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineTextItem.cpp (283079 => 283080)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineTextItem.cpp	2021-09-25 13:53:27 UTC (rev 283079)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineTextItem.cpp	2021-09-25 15:47:55 UTC (rev 283080)
@@ -78,7 +78,7 @@
         return inlineContent.append(InlineTextItem::createEmptyItem(inlineTextBox));
 
     auto& style = inlineTextBox.style();
-    auto& font = style.fontCascade();
+    auto& fontCascade = style.fontCascade();
     auto whitespaceContentIsTreatedAsSingleSpace = !TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox);
     auto shouldPreserveNewline = TextUtil::shouldPreserveNewline(inlineTextBox);
     auto shouldTreatNonBreakingSpaceAsRegularSpace = style.nbspMode() == NBSPMode::Space;
@@ -88,7 +88,7 @@
     auto inlineItemWidth = [&](auto startPosition, auto length) -> std::optional<InlineLayoutUnit> {
         if (!inlineTextBox.canUseSimplifiedContentMeasuring())
             return { };
-        return TextUtil::width(inlineTextBox, startPosition, startPosition + length, { });
+        return TextUtil::width(inlineTextBox, fontCascade, startPosition, startPosition + length, { });
     };
 
     while (currentPosition < text.length()) {
@@ -107,7 +107,7 @@
             ASSERT(whitespaceContent->length);
             auto appendWhitespaceItem = [&] (auto startPosition, auto itemLength) {
                 auto simpleSingleWhitespaceContent = inlineTextBox.canUseSimplifiedContentMeasuring() && (itemLength == 1 || whitespaceContentIsTreatedAsSingleSpace);
-                auto width = simpleSingleWhitespaceContent ? std::make_optional(InlineLayoutUnit { font.spaceWidth() }) : inlineItemWidth(startPosition, itemLength);
+                auto width = simpleSingleWhitespaceContent ? std::make_optional(InlineLayoutUnit { fontCascade.spaceWidth() }) : inlineItemWidth(startPosition, itemLength);
                 inlineContent.append(InlineTextItem::createWhitespaceItem(inlineTextBox, startPosition, itemLength, whitespaceContent->isWordSeparator, width));
             };
             if (style.whiteSpace() == WhiteSpace::BreakSpaces) {

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp (283079 => 283080)


--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2021-09-25 13:53:27 UTC (rev 283079)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2021-09-25 15:47:55 UTC (rev 283080)
@@ -40,48 +40,46 @@
 namespace WebCore {
 namespace Layout {
 
-InlineLayoutUnit TextUtil::width(const InlineTextItem& inlineTextItem, InlineLayoutUnit contentLogicalLeft)
+InlineLayoutUnit TextUtil::width(const InlineTextItem& inlineTextItem, const FontCascade& fontCascade, InlineLayoutUnit contentLogicalLeft)
 {
-    return TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.end(), contentLogicalLeft);
+    return TextUtil::width(inlineTextItem, fontCascade, inlineTextItem.start(), inlineTextItem.end(), contentLogicalLeft);
 }
 
-InlineLayoutUnit TextUtil::width(const InlineTextItem& inlineTextItem, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft)
+InlineLayoutUnit TextUtil::width(const InlineTextItem& inlineTextItem, const FontCascade& fontCascade, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft)
 {
     RELEASE_ASSERT(from >= inlineTextItem.start());
     RELEASE_ASSERT(to <= inlineTextItem.end());
-    if (inlineTextItem.isWhitespace() && !InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
-        auto spaceWidth = inlineTextItem.style().fontCascade().spaceWidth();
+    if (inlineTextItem.isWhitespace() && !TextUtil::shouldPreserveSpacesAndTabs(inlineTextItem.layoutBox())) {
+        auto spaceWidth = fontCascade.spaceWidth();
         return std::isnan(spaceWidth) ? 0.0f : std::isinf(spaceWidth) ? maxInlineLayoutUnit() : spaceWidth;
     }
-    return TextUtil::width(inlineTextItem.inlineTextBox(), from, to, contentLogicalLeft);
+    return TextUtil::width(inlineTextItem.inlineTextBox(), fontCascade, from, to, contentLogicalLeft);
 }
 
-InlineLayoutUnit TextUtil::width(const InlineTextBox& inlineTextBox, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft)
+InlineLayoutUnit TextUtil::width(const InlineTextBox& inlineTextBox, const FontCascade& fontCascade, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft)
 {
     if (from == to)
         return 0;
 
-    auto& style = inlineTextBox.style();
-    auto& font = style.fontCascade();
     auto text = inlineTextBox.content();
     ASSERT(to <= text.length());
-    auto hasKerningOrLigatures = font.enableKerning() || font.requiresShaping();
+    auto hasKerningOrLigatures = fontCascade.enableKerning() || fontCascade.requiresShaping();
     auto measureWithEndSpace = hasKerningOrLigatures && to < text.length() && text[to] == ' ';
     if (measureWithEndSpace)
         ++to;
     float width = 0;
     if (inlineTextBox.canUseSimplifiedContentMeasuring())
-        width = font.widthForSimpleText(StringView(text).substring(from, to - from));
+        width = fontCascade.widthForSimpleText(StringView(text).substring(from, to - from));
     else {
-        auto tabWidth = style.collapseWhiteSpace() ? TabSize(0) : style.tabSize();
         WebCore::TextRun run(StringView(text).substring(from, to - from), contentLogicalLeft);
-        if (tabWidth)
-            run.setTabSize(true, tabWidth);
-        width = font.width(run);
+        auto& style = inlineTextBox.style();
+        if (!style.collapseWhiteSpace() && style.tabSize() > 0)
+            run.setTabSize(true, style.tabSize());
+        width = fontCascade.width(run);
     }
 
     if (measureWithEndSpace)
-        width -= (font.spaceWidth() + font.wordSpacing());
+        width -= (fontCascade.spaceWidth() + fontCascade.wordSpacing());
 
     return std::isnan(width) ? 0.0f : std::isinf(width) ? maxInlineLayoutUnit() : width;
 }
@@ -138,7 +136,7 @@
     return fallbackFonts;
 }
 
-TextUtil::MidWordBreak TextUtil::midWordBreak(const InlineTextItem& inlineTextItem, InlineLayoutUnit textWidth, InlineLayoutUnit availableWidth, InlineLayoutUnit contentLogicalLeft)
+TextUtil::MidWordBreak TextUtil::midWordBreak(const InlineTextItem& inlineTextItem, const FontCascade& fontCascade, InlineLayoutUnit textWidth, InlineLayoutUnit availableWidth, InlineLayoutUnit contentLogicalLeft)
 {
     ASSERT(availableWidth >= 0);
     auto startPosition = inlineTextItem.start();
@@ -166,7 +164,7 @@
     auto leftSideWidth = InlineLayoutUnit { 0 };
     while (left < right) {
         auto middle = surrogatePairAwareIndex((left + right) / 2);
-        auto width = TextUtil::width(inlineTextItem, startPosition, middle + 1, contentLogicalLeft);
+        auto width = TextUtil::width(inlineTextItem, fontCascade, startPosition, middle + 1, contentLogicalLeft);
         if (width < availableWidth) {
             left = middle + 1;
             leftSideWidth = width;

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h (283079 => 283080)


--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h	2021-09-25 13:53:27 UTC (rev 283079)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h	2021-09-25 15:47:55 UTC (rev 283080)
@@ -44,9 +44,9 @@
 
 class TextUtil {
 public:
-    static InlineLayoutUnit width(const InlineTextItem&, InlineLayoutUnit contentLogicalLeft);
-    static InlineLayoutUnit width(const InlineTextItem&, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft);
-    static InlineLayoutUnit width(const InlineTextBox&, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft);
+    static InlineLayoutUnit width(const InlineTextItem&, const FontCascade&, InlineLayoutUnit contentLogicalLeft);
+    static InlineLayoutUnit width(const InlineTextItem&, const FontCascade&, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft);
+    static InlineLayoutUnit width(const InlineTextBox&, const FontCascade&, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft);
 
     using FallbackFontList = HashSet<const Font*>;
     static FallbackFontList fallbackFontsForRun(const Line::Run&, const RenderStyle&);
@@ -56,7 +56,7 @@
         size_t length { 0 };
         InlineLayoutUnit logicalWidth { 0 };
     };
-    static MidWordBreak midWordBreak(const InlineTextItem&, InlineLayoutUnit textWidth, InlineLayoutUnit availableWidth, InlineLayoutUnit contentLogicalLeft);
+    static MidWordBreak midWordBreak(const InlineTextItem&, const FontCascade&, InlineLayoutUnit textWidth, InlineLayoutUnit availableWidth, InlineLayoutUnit contentLogicalLeft);
 
     static unsigned findNextBreakablePosition(LazyLineBreakIterator&, unsigned startPosition, const RenderStyle&);
     static LineBreakIteratorMode lineBreakIteratorMode(LineBreak);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to