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);