Diff
Modified: trunk/Source/WebCore/ChangeLog (287492 => 287493)
--- trunk/Source/WebCore/ChangeLog 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/ChangeLog 2021-12-31 14:21:02 UTC (rev 287493)
@@ -1,3 +1,34 @@
+2021-12-31 Alan Bujtas <[email protected]>
+
+ [LFC][IFC] Take grapheme clusters into account when keeping the first "character" on the line
+ https://bugs.webkit.org/show_bug.cgi?id=234758
+
+ Reviewed by Antti Koivisto.
+
+ When dealing with complex fonts, we have to start looking beyond code points and taking
+ larger cluster of code units into account.
+
+ This patch is in preparation for enabling complex font codepath.
+
+ * layout/formattingContexts/inline/InlineContentBreaker.cpp:
+ (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
+ * layout/formattingContexts/inline/text/TextUtil.cpp:
+ (WebCore::Layout::TextUtil::firstUserPerceivedCharacterLength): user-perceived character is a unicode term.
+ see https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
+ * layout/formattingContexts/inline/text/TextUtil.h:
+ * layout/integration/LayoutIntegrationBoxTree.cpp:
+ (WebCore::LayoutIntegration::BoxTree::buildTree):
+ * layout/layouttree/LayoutInlineTextBox.cpp:
+ (WebCore::Layout::InlineTextBox::InlineTextBox):
+ (WebCore::Layout::m_canUseSimpleFontCodePath):
+ (WebCore::Layout::m_canUseSimplifiedContentMeasuring): Deleted.
+ * layout/layouttree/LayoutInlineTextBox.h:
+ (WebCore::Layout::InlineTextBox::canUseSimpleFontCodePath const):
+ * layout/layouttree/LayoutTreeBuilder.cpp:
+ (WebCore::Layout::TreeBuilder::createTextBox):
+ (WebCore::Layout::TreeBuilder::createLayoutBox):
+ * layout/layouttree/LayoutTreeBuilder.h:
+
2021-12-30 Jean-Yves Avenard <[email protected]>
SharedBuffer::takeData() is still dangerous
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp (287492 => 287493)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp 2021-12-31 14:21:02 UTC (rev 287493)
@@ -208,26 +208,17 @@
auto leadingTextRunIndex = *firstTextRunIndex(continuousContent);
auto& leadingTextRun = continuousContent.runs()[leadingTextRunIndex];
auto& inlineTextItem = downcast<InlineTextItem>(leadingTextRun.inlineItem);
- auto firstCodePointLength = [&]() -> size_t {
- auto textContent = inlineTextItem.inlineTextBox().content();
- if (textContent.is8Bit())
- return 1;
- UChar32 character;
- size_t endOfCodePoint = 0;
- U16_NEXT(textContent.characters16(), endOfCodePoint, textContent.length(), character);
- return endOfCodePoint;
- }();
+ auto firstCharacterLength = TextUtil::firstUserPerceivedCharacterLength(inlineTextItem);
+ ASSERT(firstCharacterLength > 0);
- if (inlineTextItem.length() <= firstCodePointLength) {
- if (continuousContent.runs().size() == 1) {
- // Let's return single, leading text items as is.
+ if (inlineTextItem.length() <= firstCharacterLength) {
+ if (continuousContent.runs().size() == 1)
return Result { Result::Action::Keep, IsEndOfLine::Yes };
- }
return Result { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, { } } };
}
- 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 } } };
+ auto firstCharacterWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade(), inlineTextItem.start(), inlineTextItem.start() + firstCharacterLength, lineStatus.contentLogicalRight);
+ return Result { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, PartialRun { firstCharacterLength, firstCharacterWidth } } };
}
if (trailingContent->overflows && lineStatus.hasContent) {
// We managed to break a run with overflow but the line already has content. Let's wrap it to the next line.
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp (287492 => 287493)
--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp 2021-12-31 14:21:02 UTC (rev 287493)
@@ -36,6 +36,7 @@
#include "RenderBox.h"
#include "RenderStyle.h"
#include "SurrogatePairAwareTextIterator.h"
+#include <wtf/text/TextBreakIterator.h>
namespace WebCore {
namespace Layout {
@@ -274,6 +275,27 @@
return false;
}
+size_t TextUtil::firstUserPerceivedCharacterLength(const InlineTextItem& inlineTextItem)
+{
+ auto& inlineTextBox = inlineTextItem.inlineTextBox();
+ auto textContent = inlineTextBox.content();
+ RELEASE_ASSERT(!textContent.isEmpty());
+
+ if (textContent.is8Bit())
+ return 1;
+ if (inlineTextBox.canUseSimpleFontCodePath()) {
+ UChar32 character;
+ size_t endOfCodePoint = 0;
+ U16_NEXT(textContent.characters16(), endOfCodePoint, textContent.length(), character);
+ return endOfCodePoint;
+ }
+ auto graphemeClustersIterator = NonSharedCharacterBreakIterator { textContent };
+ auto nextPosition = ubrk_following(graphemeClustersIterator, inlineTextItem.start());
+ if (nextPosition == UBRK_DONE)
+ return inlineTextItem.length();
+ return nextPosition - inlineTextItem.start();
}
+
}
+}
#endif
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h (287492 => 287493)
--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h 2021-12-31 14:21:02 UTC (rev 287493)
@@ -65,6 +65,8 @@
static bool shouldPreserveNewline(const Box&);
static bool isWrappingAllowed(const RenderStyle&);
static bool containsStrongDirectionalityText(StringView);
+
+ static size_t firstUserPerceivedCharacterLength(const InlineTextItem&);
};
}
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp (287492 => 287493)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp 2021-12-31 14:21:02 UTC (rev 287493)
@@ -98,7 +98,7 @@
auto style = RenderStyle::createAnonymousStyleWithDisplay(textRenderer.style(), DisplayType::Inline);
auto text = style.textSecurity() == TextSecurity::None ? textRenderer.text() : RenderBlock::updateSecurityDiscCharacters(style, textRenderer.text());
auto useSimplifiedTextMeasuring = textRenderer.canUseSimplifiedTextMeasuring() && (!firstLineStyle || firstLineStyle->fontCascade() == style.fontCascade());
- return makeUnique<Layout::InlineTextBox>(text, useSimplifiedTextMeasuring, WTFMove(style), WTFMove(firstLineStyle));
+ return makeUnique<Layout::InlineTextBox>(text, useSimplifiedTextMeasuring, textRenderer.canUseSimpleFontCodePath(), WTFMove(style), WTFMove(firstLineStyle));
}
auto style = RenderStyle::clone(childRenderer.style());
Modified: trunk/Source/WebCore/layout/layouttree/LayoutInlineTextBox.cpp (287492 => 287493)
--- trunk/Source/WebCore/layout/layouttree/LayoutInlineTextBox.cpp 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/layouttree/LayoutInlineTextBox.cpp 2021-12-31 14:21:02 UTC (rev 287493)
@@ -36,10 +36,11 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(InlineTextBox);
-InlineTextBox::InlineTextBox(String content, bool canUseSimplifiedContentMeasuring, RenderStyle&& style, std::unique_ptr<RenderStyle>&& firstLineStyle)
+InlineTextBox::InlineTextBox(String content, bool canUseSimplifiedContentMeasuring, bool canUseSimpleFontCodePath, RenderStyle&& style, std::unique_ptr<RenderStyle>&& firstLineStyle)
: Box({ }, WTFMove(style), WTFMove(firstLineStyle), Box::InlineTextBoxFlag)
, m_content(content)
, m_canUseSimplifiedContentMeasuring(canUseSimplifiedContentMeasuring)
+ , m_canUseSimpleFontCodePath(canUseSimpleFontCodePath)
{
setIsAnonymous();
}
Modified: trunk/Source/WebCore/layout/layouttree/LayoutInlineTextBox.h (287492 => 287493)
--- trunk/Source/WebCore/layout/layouttree/LayoutInlineTextBox.h 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/layouttree/LayoutInlineTextBox.h 2021-12-31 14:21:02 UTC (rev 287493)
@@ -37,16 +37,18 @@
class InlineTextBox : public Box {
WTF_MAKE_ISO_ALLOCATED(InlineTextBox);
public:
- InlineTextBox(String, bool canUseSimplifiedContentMeasuring, RenderStyle&&, std::unique_ptr<RenderStyle>&& firstLineStyle = nullptr);
+ InlineTextBox(String, bool canUseSimplifiedContentMeasuring, bool canUseSimpleFontCodePath, RenderStyle&&, std::unique_ptr<RenderStyle>&& firstLineStyle = nullptr);
virtual ~InlineTextBox() = default;
String content() const { return m_content; }
// FIXME: This should not be a box's property.
bool canUseSimplifiedContentMeasuring() const { return m_canUseSimplifiedContentMeasuring; }
+ bool canUseSimpleFontCodePath() const { return m_canUseSimpleFontCodePath; }
private:
String m_content;
bool m_canUseSimplifiedContentMeasuring { false };
+ bool m_canUseSimpleFontCodePath { true };
};
}
Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp (287492 => 287493)
--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2021-12-31 14:21:02 UTC (rev 287493)
@@ -132,9 +132,9 @@
return makeUnique<ReplacedBox>(elementAttributes, WTFMove(style));
}
-std::unique_ptr<Box> TreeBuilder::createTextBox(String text, bool canUseSimplifiedTextMeasuring, RenderStyle&& style)
+std::unique_ptr<Box> TreeBuilder::createTextBox(String text, bool canUseSimplifiedTextMeasuring, bool canUseSimpleFontCodePath, RenderStyle&& style)
{
- return makeUnique<InlineTextBox>(text, canUseSimplifiedTextMeasuring, WTFMove(style));
+ return makeUnique<InlineTextBox>(text, canUseSimplifiedTextMeasuring, canUseSimpleFontCodePath, WTFMove(style));
}
std::unique_ptr<Box> TreeBuilder::createLineBreakBox(bool isOptional, RenderStyle&& style)
@@ -171,9 +171,9 @@
String text = textRenderer.text();
auto useSimplifiedTextMeasuring = canUseSimplifiedTextMeasuring(text, parentContainer.style().fontCascade(), parentContainer.style().collapseWhiteSpace());
if (parentContainer.style().display() == DisplayType::Inline)
- childLayoutBox = createTextBox(text, useSimplifiedTextMeasuring, RenderStyle::clone(parentContainer.style()));
+ childLayoutBox = createTextBox(text, useSimplifiedTextMeasuring, textRenderer.canUseSimpleFontCodePath(), RenderStyle::clone(parentContainer.style()));
else
- childLayoutBox = createTextBox(text, useSimplifiedTextMeasuring, RenderStyle::createAnonymousStyleWithDisplay(parentContainer.style(), DisplayType::Inline));
+ childLayoutBox = createTextBox(text, useSimplifiedTextMeasuring, textRenderer.canUseSimpleFontCodePath(), RenderStyle::createAnonymousStyleWithDisplay(parentContainer.style(), DisplayType::Inline));
} else {
auto& renderer = downcast<RenderElement>(childRenderer);
auto displayType = renderer.style().display();
Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h (287492 => 287493)
--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h 2021-12-31 10:11:40 UTC (rev 287492)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h 2021-12-31 14:21:02 UTC (rev 287493)
@@ -67,7 +67,7 @@
std::unique_ptr<Box> createLayoutBox(const ContainerBox& parentContainer, const RenderObject& childRenderer);
std::unique_ptr<Box> createReplacedBox(std::optional<Box::ElementAttributes>, RenderStyle&&);
- std::unique_ptr<Box> createTextBox(String text, bool canUseSimplifiedTextMeasuring, RenderStyle&&);
+ std::unique_ptr<Box> createTextBox(String text, bool canUseSimplifiedTextMeasuring, bool canUseSimpleFontCodePath, RenderStyle&&);
std::unique_ptr<Box> createLineBreakBox(bool isOptional, RenderStyle&&);
std::unique_ptr<ContainerBox> createContainer(std::optional<Box::ElementAttributes>, RenderStyle&&);
};