Title: [282735] trunk/Source/WebCore
Revision
282735
Author
[email protected]
Date
2021-09-19 07:27:51 -0700 (Sun, 19 Sep 2021)

Log Message

[LFC][Integration] Paint LFC text runs with TextBoxPainter
https://bugs.webkit.org/show_bug.cgi?id=230455

Reviewed by Alan Bujtas.

This will give LFC path all the same painting features (including selections, markers etc) that
the legacy path has. This patch does not enable any new features yet.

* layout/integration/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::paint):
(WebCore::LayoutIntegration::LineLayout::paintTextRunUsingPhysicalCoordinates):

Use TextBoxPainter.

* layout/integration/LayoutIntegrationLineLayout.h:
* rendering/LegacyInlineTextBox.cpp:
(WebCore::LegacyInlineTextBox::textOriginFromBoxRect const): Deleted.
(WebCore::LegacyInlineTextBox::debugTextShadow const): Deleted.
* rendering/LegacyInlineTextBox.h:
* rendering/TextBoxPainter.cpp:
(WebCore::TextBoxPainter::TextBoxPainter):

TextBoxPainter now uses the inline iterator instead of directly accessing LegacyInlineTextBox.

(WebCore::TextBoxPainter::paint):
(WebCore::TextBoxPainter::createMarkedTextFromSelectionInBox):
(WebCore::TextBoxPainter::paintBackground):
(WebCore::TextBoxPainter::paintForegroundAndDecorations):
(WebCore::TextBoxPainter::paintCompositionBackground):
(WebCore::TextBoxPainter::paintForeground):
(WebCore::TextBoxPainter::paintDecoration):
(WebCore::TextBoxPainter::paintCompositionUnderlines):
(WebCore::textPosition):
(WebCore::TextBoxPainter::paintCompositionUnderline):
(WebCore::TextBoxPainter::paintPlatformDocumentMarkers):
(WebCore::TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds):
(WebCore::TextBoxPainter::computePaintRect):
(WebCore::fontCascadeFor):
(WebCore::TextBoxPainter::calculateDocumentMarkerBounds):
(WebCore::TextBoxPainter::computeHaveSelection const):
(WebCore::TextBoxPainter::combinedText const):
(WebCore::TextBoxPainter::fontCascade const):
(WebCore::TextBoxPainter::textOriginFromPaintRect const):
(WebCore::TextBoxPainter::debugTextShadow const):
(WebCore::createMarkedTextFromSelectionInBox): Deleted.
* rendering/TextBoxPainter.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (282734 => 282735)


--- trunk/Source/WebCore/ChangeLog	2021-09-19 04:25:25 UTC (rev 282734)
+++ trunk/Source/WebCore/ChangeLog	2021-09-19 14:27:51 UTC (rev 282735)
@@ -1,3 +1,52 @@
+2021-09-19  Antti Koivisto  <[email protected]>
+
+        [LFC][Integration] Paint LFC text runs with TextBoxPainter
+        https://bugs.webkit.org/show_bug.cgi?id=230455
+
+        Reviewed by Alan Bujtas.
+
+        This will give LFC path all the same painting features (including selections, markers etc) that
+        the legacy path has. This patch does not enable any new features yet.
+
+        * layout/integration/LayoutIntegrationLineLayout.cpp:
+        (WebCore::LayoutIntegration::LineLayout::paint):
+        (WebCore::LayoutIntegration::LineLayout::paintTextRunUsingPhysicalCoordinates):
+
+        Use TextBoxPainter.
+
+        * layout/integration/LayoutIntegrationLineLayout.h:
+        * rendering/LegacyInlineTextBox.cpp:
+        (WebCore::LegacyInlineTextBox::textOriginFromBoxRect const): Deleted.
+        (WebCore::LegacyInlineTextBox::debugTextShadow const): Deleted.
+        * rendering/LegacyInlineTextBox.h:
+        * rendering/TextBoxPainter.cpp:
+        (WebCore::TextBoxPainter::TextBoxPainter):
+
+        TextBoxPainter now uses the inline iterator instead of directly accessing LegacyInlineTextBox.
+
+        (WebCore::TextBoxPainter::paint):
+        (WebCore::TextBoxPainter::createMarkedTextFromSelectionInBox):
+        (WebCore::TextBoxPainter::paintBackground):
+        (WebCore::TextBoxPainter::paintForegroundAndDecorations):
+        (WebCore::TextBoxPainter::paintCompositionBackground):
+        (WebCore::TextBoxPainter::paintForeground):
+        (WebCore::TextBoxPainter::paintDecoration):
+        (WebCore::TextBoxPainter::paintCompositionUnderlines):
+        (WebCore::textPosition):
+        (WebCore::TextBoxPainter::paintCompositionUnderline):
+        (WebCore::TextBoxPainter::paintPlatformDocumentMarkers):
+        (WebCore::TextBoxPainter::calculateUnionOfAllDocumentMarkerBounds):
+        (WebCore::TextBoxPainter::computePaintRect):
+        (WebCore::fontCascadeFor):
+        (WebCore::TextBoxPainter::calculateDocumentMarkerBounds):
+        (WebCore::TextBoxPainter::computeHaveSelection const):
+        (WebCore::TextBoxPainter::combinedText const):
+        (WebCore::TextBoxPainter::fontCascade const):
+        (WebCore::TextBoxPainter::textOriginFromPaintRect const):
+        (WebCore::TextBoxPainter::debugTextShadow const):
+        (WebCore::createMarkedTextFromSelectionInBox): Deleted.
+        * rendering/TextBoxPainter.h:
+
 2021-09-18  Myles C. Maxfield  <[email protected]>
 
         [Cocoa] Add "Shaping" log channel

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp (282734 => 282735)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2021-09-19 04:25:25 UTC (rev 282734)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2021-09-19 14:27:51 UTC (rev 282735)
@@ -53,8 +53,8 @@
 #include "RenderView.h"
 #include "RuntimeEnabledFeatures.h"
 #include "Settings.h"
+#include "TextBoxPainter.h"
 #include "TextDecorationPainter.h"
-#include "TextPainter.h"
 
 namespace WebCore {
 namespace LayoutIntegration {
@@ -501,9 +501,11 @@
     for (auto& run : m_inlineContent->runsForRect(paintRect)) {
         if (run.isInlineBox())
             continue;
-        if (run.text())
-            paintTextRunUsingPhysicalCoordinates(paintInfo, paintOffset, m_inlineContent->lineForRun(run), run);
-        else if (auto& renderer = m_boxTree.rendererForLayoutBox(run.layoutBox()); is<RenderBox>(renderer) && renderer.isReplaced()) {
+        if (run.text()) {
+            paintTextRunUsingPhysicalCoordinates(paintInfo, paintOffset, run);
+            continue;
+        }
+        if (auto& renderer = m_boxTree.rendererForLayoutBox(run.layoutBox()); is<RenderBox>(renderer) && renderer.isReplaced()) {
             auto& renderBox = downcast<RenderBox>(renderer);
             if (!renderBox.hasSelfPaintingLayer() && paintInfo.shouldPaintWithinRoot(renderBox))
                 renderBox.paintAsInlineBlock(paintInfo, paintOffset);
@@ -570,7 +572,7 @@
         m_inlineContent->releaseCaches();
 }
 
-void LineLayout::paintTextRunUsingPhysicalCoordinates(PaintInfo& paintInfo, const LayoutPoint& paintOffset, const Line& line, const Layout::Run& run)
+void LineLayout::paintTextRunUsingPhysicalCoordinates(PaintInfo& paintInfo, const LayoutPoint& paintOffset, const Layout::Run& run)
 {
     auto& style = run.style();
     if (run.style().visibility() != Visibility::Visible)
@@ -604,49 +606,8 @@
     if (damagedRect.y() > visualOverflowRect.maxY() || damagedRect.maxY() < visualOverflowRect.y())
         return;
 
-    if (paintInfo.eventRegionContext) {
-        if (style.pointerEvents() != PointerEvents::None) {
-            visualOverflowRect.moveBy(physicalPaintOffset);
-            paintInfo.eventRegionContext->unite(enclosingIntRect(visualOverflowRect), style);
-        }
-        return;
-    }
-
-    auto& paintContext = paintInfo.context();
-    auto expansion = run.expansion();
-    // TextRun expects the xPos to be adjusted with the aligment offset (e.g. when the line is center aligned
-    // and the run starts at 100px, due to the horizontal aligment, the xpos is supposed to be at 0px).
-    auto& fontCascade = style.fontCascade();
-    auto xPos = run.logicalRect().left() - (line.lineBoxLeft() + line.contentLeft());
-    auto textRun = WebCore::TextRun { textContent.renderedContent(), xPos, expansion.horizontalExpansion, expansion.behavior };
-    textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
-
-    auto textPainter = TextPainter { paintContext };
-    textPainter.setFont(fontCascade);
-    textPainter.setStyle(computeTextPaintStyle(formattingContextRoot.frame(), style, paintInfo));
-    textPainter.setGlyphDisplayListIfNeeded(run, paintInfo, fontCascade, paintContext, textRun);
-
-    // Painting uses only physical coordinates.
-    {
-        auto runRect = physicalRect(run.logicalRect());
-        auto boxRect = FloatRect { FloatPoint { physicalPaintOffset.x() + runRect.x(), physicalPaintOffset.y() + runRect.y() }, runRect.size() };
-        auto textOrigin = FloatPoint { boxRect.x(), roundToDevicePixel(boxRect.y() + fontCascade.fontMetrics().ascent(), formattingContextRoot.document().deviceScaleFactor()) };
-
-        auto shouldRotate = !blockIsHorizontalWriting;
-        if (shouldRotate)
-            paintContext.concatCTM(rotation(boxRect, Clockwise));
-        textPainter.paint(textRun, runRect, textOrigin);
-
-        if (!style.textDecorationsInEffect().isEmpty()) {
-            auto& textRenderer = downcast<RenderText>(m_boxTree.rendererForLayoutBox(run.layoutBox()));
-            auto decorationPainter = TextDecorationPainter { paintContext, style.textDecorationsInEffect(), textRenderer, false, fontCascade };
-            decorationPainter.setTextRunIterator(textRunFor(*m_inlineContent, run));
-            decorationPainter.setWidth(runRect.width());
-            decorationPainter.paintTextDecoration(textRun, textOrigin, runRect.location() + physicalPaintOffset);
-        }
-        if (shouldRotate)
-            paintInfo.context().concatCTM(rotation(boxRect, Counterclockwise));
-    }
+    TextBoxPainter painter(*m_inlineContent, run, paintInfo, paintOffset);
+    painter.paint();
 }
 
 Layout::InlineDamage& LineLayout::ensureLineDamage()

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h (282734 => 282735)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2021-09-19 04:25:25 UTC (rev 282734)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2021-09-19 14:27:51 UTC (rev 282735)
@@ -123,7 +123,7 @@
     InlineContent& ensureInlineContent();
     void updateLayoutBoxDimensions(const RenderBox&);
 
-    void paintTextRunUsingPhysicalCoordinates(PaintInfo&, const LayoutPoint& paintOffset, const Line&, const Layout::Run&);
+    void paintTextRunUsingPhysicalCoordinates(PaintInfo&, const LayoutPoint& paintOffset, const Layout::Run&);
 
     Layout::InlineDamage& ensureLineDamage();
 

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp (282734 => 282735)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-09-19 04:25:25 UTC (rev 282734)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-09-19 14:27:51 UTC (rev 282735)
@@ -433,20 +433,6 @@
     return MarkedText::collectForDocumentMarkers(renderer(), selectableRange(), MarkedText::PaintPhase::Decoration).size();
 }
 
-FloatPoint LegacyInlineTextBox::textOriginFromBoxRect(const FloatRect& boxRect) const
-{
-    FloatPoint textOrigin { boxRect.x(), boxRect.y() + lineFont().fontMetrics().ascent() };
-    if (auto* combinedText = this->combinedText()) {
-        if (auto newOrigin = combinedText->computeTextOrigin(boxRect))
-            textOrigin = newOrigin.value();
-    }
-    if (isHorizontal())
-        textOrigin.setY(roundToDevicePixel(LayoutUnit { textOrigin.y() }, renderer().document().deviceScaleFactor()));
-    else
-        textOrigin.setX(roundToDevicePixel(LayoutUnit { textOrigin.x() }, renderer().document().deviceScaleFactor()));
-    return textOrigin;
-}
-
 int LegacyInlineTextBox::caretMinOffset() const
 {
     return m_start;
@@ -540,15 +526,6 @@
     return lineStyle().hasTextCombine() && is<RenderCombineText>(renderer()) && downcast<RenderCombineText>(renderer()).isCombined() ? &downcast<RenderCombineText>(renderer()) : nullptr;
 }
 
-const ShadowData* LegacyInlineTextBox::debugTextShadow() const
-{
-    if (!renderer().settings().legacyLineLayoutVisualCoverageEnabled())
-        return nullptr;
-
-    static NeverDestroyed<ShadowData> debugTextShadow(IntPoint(0, 0), 10, 20, ShadowStyle::Normal, true, SRGBA<uint8_t> { 150, 0, 0, 190 });
-    return &debugTextShadow.get();
-}
-
 ExpansionBehavior LegacyInlineTextBox::expansionBehavior() const
 {
     ExpansionBehavior leftBehavior;

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.h (282734 => 282735)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-09-19 04:25:25 UTC (rev 282734)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-09-19 14:27:51 UTC (rev 282735)
@@ -157,13 +157,9 @@
     friend class LayoutIntegration::RunIteratorLegacyPath;
     friend class TextBoxPainter;
 
-    FloatPoint textOriginFromBoxRect(const FloatRect&) const;
-
     const RenderCombineText* combinedText() const;
     const FontCascade& lineFont() const;
 
-    const ShadowData* debugTextShadow() const;
-
     String text(bool ignoreCombinedText = false, bool ignoreHyphen = false) const; // The effective text for the run.
     TextRun createTextRun(bool ignoreCombinedText = false, bool ignoreHyphen = false) const;
 

Modified: trunk/Source/WebCore/rendering/TextBoxPainter.cpp (282734 => 282735)


--- trunk/Source/WebCore/rendering/TextBoxPainter.cpp	2021-09-19 04:25:25 UTC (rev 282734)
+++ trunk/Source/WebCore/rendering/TextBoxPainter.cpp	2021-09-19 14:27:51 UTC (rev 282735)
@@ -29,10 +29,14 @@
 #include "Editor.h"
 #include "EventRegion.h"
 #include "GraphicsContext.h"
+#include "LayoutIntegrationLineIterator.h"
+#include "LayoutIntegrationRunIterator.h"
 #include "LegacyInlineTextBox.h"
 #include "PaintInfo.h"
 #include "RenderBlock.h"
+#include "RenderCombineText.h"
 #include "RenderText.h"
+#include "ShadowData.h"
 #include "StyledMarkedText.h"
 #include "TextPaintStyle.h"
 #include "TextPainter.h"
@@ -40,13 +44,28 @@
 namespace WebCore {
 
 TextBoxPainter::TextBoxPainter(const LegacyInlineTextBox& textBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
-    : m_textBox(textBox)
-    , m_renderer(textBox.renderer())
+    : TextBoxPainter(LayoutIntegration::textRunFor(&textBox), paintInfo, paintOffset)
+{
+    m_emphasisMarkExistsAndIsAbove = textBox.emphasisMarkExistsAndIsAbove(m_style);
+}
+
+TextBoxPainter::TextBoxPainter(const LayoutIntegration::InlineContent& inlineContent, const Layout::Run& run, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+    : TextBoxPainter(LayoutIntegration::textRunFor(inlineContent, run), paintInfo, paintOffset)
+{
+}
+
+TextBoxPainter::TextBoxPainter(LayoutIntegration::TextRunIterator&& textBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+    : m_textBox(WTFMove(textBox))
+    , m_renderer(m_textBox->renderer())
     , m_document(m_renderer.document())
+    , m_style(m_textBox->style())
+    , m_paintTextRun(m_textBox->createTextRun())
     , m_paintInfo(paintInfo)
-    , m_paintRect(computePaintRect(textBox, paintOffset))
+    , m_selectableRange(m_textBox->selectableRange())
+    , m_paintRect(computePaintRect(paintOffset))
+    , m_isFirstLine(m_textBox->line()->isFirst())
     , m_isPrinting(m_document.printing())
-    , m_haveSelection(!m_isPrinting && m_paintInfo.phase != PaintPhase::TextClip && m_textBox.selectionState() != RenderObject::HighlightState::None)
+    , m_haveSelection(computeHaveSelection())
     , m_containsComposition(m_renderer.textNode() && m_renderer.frame().editor().compositionNode() == m_renderer.textNode())
     , m_useCustomUnderlines(m_containsComposition && m_renderer.frame().editor().compositionUsesCustomUnderlines())
 {
@@ -64,11 +83,11 @@
 
     if (m_paintInfo.phase == PaintPhase::EventRegion) {
         if (m_renderer.parent()->visibleToHitTesting())
-            m_paintInfo.eventRegionContext->unite(enclosingIntRect(m_paintRect), m_renderer.style());
+            m_paintInfo.eventRegionContext->unite(enclosingIntRect(m_paintRect), m_style);
         return;
     }
 
-    bool shouldRotate = !m_textBox.isHorizontal() && !m_textBox.combinedText();
+    bool shouldRotate = !textBox().isHorizontal() && !combinedText();
     if (shouldRotate)
         m_paintInfo.context().concatCTM(rotation(m_paintRect, Clockwise));
 
@@ -92,9 +111,9 @@
         m_paintInfo.context().concatCTM(rotation(m_paintRect, Counterclockwise));
 }
 
-static MarkedText createMarkedTextFromSelectionInBox(const LegacyInlineTextBox& box)
+MarkedText TextBoxPainter::createMarkedTextFromSelectionInBox()
 {
-    auto [selectionStart, selectionEnd] = box.selectionStartEnd();
+    auto [selectionStart, selectionEnd] = m_renderer.view().selection().rangeForTextBox(m_renderer, m_selectableRange);
     if (selectionStart < selectionEnd)
         return { selectionStart, selectionEnd, MarkedText::Selection };
     return { };
@@ -105,20 +124,18 @@
     if (m_containsComposition && !m_useCustomUnderlines)
         paintCompositionBackground();
 
-    auto selectableRange = m_textBox.selectableRange();
-
     Vector<MarkedText> markedTexts;
-    markedTexts.appendVector(MarkedText::collectForDocumentMarkers(m_renderer, selectableRange, MarkedText::PaintPhase::Background));
-    markedTexts.appendVector(MarkedText::collectForHighlights(m_renderer, selectableRange, MarkedText::PaintPhase::Background));
+    markedTexts.appendVector(MarkedText::collectForDocumentMarkers(m_renderer, m_selectableRange, MarkedText::PaintPhase::Background));
+    markedTexts.appendVector(MarkedText::collectForHighlights(m_renderer, m_selectableRange, MarkedText::PaintPhase::Background));
 
 #if ENABLE(TEXT_SELECTION)
     if (m_haveSelection && !m_useCustomUnderlines && !m_paintInfo.context().paintingDisabled()) {
-        auto selectionMarkedText = createMarkedTextFromSelectionInBox(m_textBox);
+        auto selectionMarkedText = createMarkedTextFromSelectionInBox();
         if (!selectionMarkedText.isEmpty())
             markedTexts.append(WTFMove(selectionMarkedText));
     }
 #endif
-    auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, m_renderer, m_textBox.isFirstLine(), m_paintInfo);
+    auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, m_renderer, m_isFirstLine, m_paintInfo);
 
     // Coalesce styles of adjacent marked texts to minimize the number of drawing commands.
     auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualBackground(styledMarkedTexts);
@@ -132,18 +149,16 @@
     bool shouldPaintSelectionForeground = m_haveSelection && !m_useCustomUnderlines;
     Vector<MarkedText> markedTexts;
     if (m_paintInfo.phase != PaintPhase::Selection) {
-        auto selectableRange = m_textBox.selectableRange();
-
         // The marked texts for the gaps between document markers and selection are implicitly created by subdividing the entire line.
-        markedTexts.append({ selectableRange.clamp(m_textBox.start()), selectableRange.clamp(m_textBox.end()), MarkedText::Unmarked });
+        markedTexts.append({ m_selectableRange.clamp(textBox().start()), m_selectableRange.clamp(textBox().end()), MarkedText::Unmarked });
 
         if (!m_isPrinting) {
-            markedTexts.appendVector(MarkedText::collectForDocumentMarkers(m_renderer, selectableRange, MarkedText::PaintPhase::Foreground));
-            markedTexts.appendVector(MarkedText::collectForHighlights(m_renderer, selectableRange, MarkedText::PaintPhase::Foreground));
+            markedTexts.appendVector(MarkedText::collectForDocumentMarkers(m_renderer, m_selectableRange, MarkedText::PaintPhase::Foreground));
+            markedTexts.appendVector(MarkedText::collectForHighlights(m_renderer, m_selectableRange, MarkedText::PaintPhase::Foreground));
 
             bool shouldPaintDraggedContent = !(m_paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection));
             if (shouldPaintDraggedContent) {
-                auto markedTextsForDraggedContent = MarkedText::collectForDraggedContent(m_renderer, selectableRange);
+                auto markedTextsForDraggedContent = MarkedText::collectForDraggedContent(m_renderer, m_selectableRange);
                 if (!markedTextsForDraggedContent.isEmpty()) {
                     shouldPaintSelectionForeground = false;
                     markedTexts.appendVector(markedTextsForDraggedContent);
@@ -154,12 +169,12 @@
     // The selection marked text acts as a placeholder when computing the marked texts for the gaps...
     if (shouldPaintSelectionForeground) {
         ASSERT(!m_isPrinting);
-        auto selectionMarkedText = createMarkedTextFromSelectionInBox(m_textBox);
+        auto selectionMarkedText = createMarkedTextFromSelectionInBox();
         if (!selectionMarkedText.isEmpty())
             markedTexts.append(WTFMove(selectionMarkedText));
     }
 
-    auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, m_renderer, m_textBox.isFirstLine(), m_paintInfo);
+    auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, m_renderer, m_isFirstLine, m_paintInfo);
 
     // ... now remove the selection marked text if we are excluding selection.
     if (!m_isPrinting && m_paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection)) {
@@ -174,16 +189,16 @@
     for (auto& markedText : coalescedStyledMarkedTexts)
         paintForeground(markedText);
 
-    auto textDecorations = m_textBox.lineStyle().textDecorationsInEffect();
-    bool highlightDecorations = !MarkedText::collectForHighlights(m_renderer, m_textBox.selectableRange(), MarkedText::PaintPhase::Decoration).isEmpty();
+    auto textDecorations = m_style.textDecorationsInEffect();
+    bool highlightDecorations = !MarkedText::collectForHighlights(m_renderer, m_selectableRange, MarkedText::PaintPhase::Decoration).isEmpty();
     bool lineDecorations = !textDecorations.isEmpty();
     if ((lineDecorations || highlightDecorations) && m_paintInfo.phase != PaintPhase::Selection) {
-        TextRun textRun = m_textBox.createTextRun();
-        unsigned length = m_textBox.truncation().value_or(textRun.length());
+        TextRun textRun = textBox().createTextRun();
+        unsigned length = m_selectableRange.truncation.value_or(textRun.length());
         unsigned selectionStart = 0;
         unsigned selectionEnd = 0;
         if (m_haveSelection)
-            std::tie(selectionStart, selectionEnd) = m_textBox.selectionStartEnd();
+            std::tie(selectionStart, selectionEnd) = m_renderer.view().selection().rangeForTextBox(m_renderer, m_selectableRange);
 
         FloatRect textDecorationSelectionClipOutRect;
         if ((m_paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection)) && selectionStart < selectionEnd && selectionEnd <= length) {
@@ -190,12 +205,12 @@
             textDecorationSelectionClipOutRect = m_paintRect;
             float logicalWidthBeforeRange;
             float logicalWidthAfterRange;
-            float logicalSelectionWidth = m_textBox.lineFont().widthOfTextRange(textRun, selectionStart, selectionEnd, nullptr, &logicalWidthBeforeRange, &logicalWidthAfterRange);
+            float logicalSelectionWidth = fontCascade().widthOfTextRange(m_paintTextRun, selectionStart, selectionEnd, nullptr, &logicalWidthBeforeRange, &logicalWidthAfterRange);
             // FIXME: Do we need to handle vertical bottom to top text?
-            if (!m_textBox.isHorizontal()) {
+            if (!textBox().isHorizontal()) {
                 textDecorationSelectionClipOutRect.move(0, logicalWidthBeforeRange);
                 textDecorationSelectionClipOutRect.setHeight(logicalSelectionWidth);
-            } else if (m_textBox.direction() == TextDirection::RTL) {
+            } else if (textBox().direction() == TextDirection::RTL) {
                 textDecorationSelectionClipOutRect.move(logicalWidthAfterRange, 0);
                 textDecorationSelectionClipOutRect.setWidth(logicalSelectionWidth);
             } else {
@@ -214,12 +229,10 @@
 
 void TextBoxPainter::paintCompositionBackground()
 {
-    auto selectableRange = m_textBox.selectableRange();
-
     auto& editor = m_renderer.frame().editor();
 
     if (!editor.compositionUsesCustomHighlights()) {
-        auto [clampedStart, clampedEnd] = selectableRange.clamp(editor.compositionStart(), editor.compositionEnd());
+        auto [clampedStart, clampedEnd] = m_selectableRange.clamp(editor.compositionStart(), editor.compositionEnd());
 
         paintBackground(clampedStart, clampedEnd, CompositionHighlight::defaultCompositionFillColor);
         return;
@@ -226,17 +239,17 @@
     }
 
     for (auto& highlight : editor.customCompositionHighlights()) {
-        if (highlight.endOffset <= m_textBox.start())
+        if (highlight.endOffset <= textBox().start())
             continue;
 
-        if (highlight.startOffset >= m_textBox.end())
+        if (highlight.startOffset >= textBox().end())
             break;
 
-        auto [clampedStart, clampedEnd] = selectableRange.clamp(highlight.startOffset, highlight.endOffset);
+        auto [clampedStart, clampedEnd] = m_selectableRange.clamp(highlight.startOffset, highlight.endOffset);
 
         paintBackground(clampedStart, clampedEnd, highlight.color, BackgroundStyle::Rounded);
 
-        if (highlight.endOffset > m_textBox.end())
+        if (highlight.endOffset > textBox().end())
             break;
     }
 }
@@ -257,22 +270,21 @@
 
     // Note that if the text is truncated, we let the thing being painted in the truncation
     // draw its own highlight.
-    TextRun textRun = m_textBox.createTextRun();
 
-    const LegacyRootInlineBox& rootBox = m_textBox.root();
-    LayoutUnit selectionBottom = rootBox.selectionBottom();
-    LayoutUnit selectionTop = rootBox.selectionTopAdjustedForPrecedingBlock();
+    const auto line = textBox().line();
+    LayoutUnit selectionBottom = line->selectionBottom();
+    LayoutUnit selectionTop = line->selectionTopAdjustedForPrecedingBlock();
 
     // Use same y positioning and height as for selection, so that when the selection and this subrange are on
     // the same word there are no pieces sticking out.
-    LayoutUnit deltaY { m_renderer.style().isFlippedLinesWritingMode() ? selectionBottom - m_textBox.logicalBottom() : m_textBox.logicalTop() - selectionTop };
+    LayoutUnit deltaY { m_style.isFlippedLinesWritingMode() ? selectionBottom - textBox().logicalBottom() : textBox().logicalTop() - selectionTop };
     LayoutUnit selectionHeight = std::max<LayoutUnit>(0, selectionBottom - selectionTop);
 
-    LayoutRect selectionRect { LayoutUnit(m_paintRect.x()), LayoutUnit(m_paintRect.y() - deltaY), LayoutUnit(m_textBox.logicalWidth()), selectionHeight };
-    m_textBox.lineFont().adjustSelectionRectForText(textRun, selectionRect, startOffset, endOffset);
+    LayoutRect selectionRect { LayoutUnit(m_paintRect.x()), LayoutUnit(m_paintRect.y() - deltaY), LayoutUnit(textBox().logicalWidth()), selectionHeight };
+    fontCascade().adjustSelectionRectForText(m_paintTextRun, selectionRect, startOffset, endOffset);
 
     // FIXME: Support painting combined text. See <https://bugs.webkit.org/show_bug.cgi?id=180993>.
-    auto backgroundRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), textRun.ltr());
+    auto backgroundRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), m_paintTextRun.ltr());
     if (backgroundStyle == BackgroundStyle::Rounded) {
         backgroundRect.expand(-1, -1);
         backgroundRect.move(0.5, 0.5);
@@ -289,30 +301,30 @@
         return;
 
     GraphicsContext& context = m_paintInfo.context();
-    const FontCascade& font = m_textBox.lineFont();
-    const RenderStyle& lineStyle = m_textBox.lineStyle();
+    const FontCascade& font = fontCascade();
 
     float emphasisMarkOffset = 0;
-    std::optional<bool> markExistsAndIsAbove = m_textBox.emphasisMarkExistsAndIsAbove(lineStyle);
-    const AtomString& emphasisMark = markExistsAndIsAbove ? lineStyle.textEmphasisMarkString() : nullAtom();
+    const AtomString& emphasisMark = m_emphasisMarkExistsAndIsAbove ? m_style.textEmphasisMarkString() : nullAtom();
     if (!emphasisMark.isEmpty())
-        emphasisMarkOffset = *markExistsAndIsAbove ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fontMetrics().descent() + font.emphasisMarkAscent(emphasisMark);
+        emphasisMarkOffset = *m_emphasisMarkExistsAndIsAbove ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fontMetrics().descent() + font.emphasisMarkAscent(emphasisMark);
 
     TextPainter textPainter { context };
     textPainter.setFont(font);
     textPainter.setStyle(markedText.style.textStyles);
-    textPainter.setIsHorizontal(m_textBox.isHorizontal());
+    textPainter.setIsHorizontal(textBox().isHorizontal());
     if (markedText.style.textShadow) {
         textPainter.setShadow(&markedText.style.textShadow.value());
-        if (lineStyle.hasAppleColorFilter())
-            textPainter.setShadowColorFilter(&lineStyle.appleColorFilter());
+        if (m_style.hasAppleColorFilter())
+            textPainter.setShadowColorFilter(&m_style.appleColorFilter());
     }
-    textPainter.setEmphasisMark(emphasisMark, emphasisMarkOffset, m_textBox.combinedText());
-    if (auto* debugShadow = m_textBox.debugTextShadow())
+    textPainter.setEmphasisMark(emphasisMark, emphasisMarkOffset, combinedText());
+    if (auto* debugShadow = debugTextShadow())
         textPainter.setShadow(debugShadow);
 
-    TextRun textRun = m_textBox.createTextRun();
-    textPainter.setGlyphDisplayListIfNeeded(m_textBox, m_paintInfo, font, context, textRun);
+    if (auto* legacyInlineBox = textBox().legacyInlineBox())
+        textPainter.setGlyphDisplayListIfNeeded(*legacyInlineBox, m_paintInfo, font, context, m_paintTextRun);
+    else
+        textPainter.setGlyphDisplayListIfNeeded(*textBox().inlineBox(), m_paintInfo, font, context, m_paintTextRun);
 
     GraphicsContextStateSaver stateSaver { context, false };
     if (markedText.type == MarkedText::DraggedContent) {
@@ -320,7 +332,7 @@
         context.setAlpha(markedText.style.alpha);
     }
     // TextPainter wants the box rectangle and text origin of the entire line box.
-    textPainter.paintRange(textRun, m_paintRect, m_textBox.textOriginFromBoxRect(m_paintRect), markedText.startOffset, markedText.endOffset);
+    textPainter.paintRange(m_paintTextRun, m_paintRect, textOriginFromPaintRect(m_paintRect), markedText.startOffset, markedText.endOffset);
 }
 
 void TextBoxPainter::paintDecoration(const StyledMarkedText& markedText, const FloatRect& clipOutRect)
@@ -332,38 +344,36 @@
         return;
 
     GraphicsContext& context = m_paintInfo.context();
-    const FontCascade& font = m_textBox.lineFont();
-    const RenderStyle& lineStyle = m_textBox.lineStyle();
+    const FontCascade& font = fontCascade();
 
     updateGraphicsContext(context, markedText.style.textStyles);
 
-    bool isCombinedText = m_textBox.combinedText();
+    bool isCombinedText = combinedText();
     if (isCombinedText)
         context.concatCTM(rotation(m_paintRect, Clockwise));
 
     // Note that if the text is truncated, we let the thing being painted in the truncation
     // draw its own decoration.
-    TextRun textRun = m_textBox.createTextRun();
 
     // Avoid measuring the text when the entire line box is selected as an optimization.
     FloatRect snappedSelectionRect = m_paintRect;
-    if (startOffset || endOffset != textRun.length()) {
+    if (startOffset || endOffset != m_paintTextRun.length()) {
         LayoutRect selectionRect = { m_paintRect.x(), m_paintRect.y(), m_paintRect.width(), m_paintRect.height() };
-        font.adjustSelectionRectForText(textRun, selectionRect, startOffset, endOffset);
-        snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), textRun.ltr());
+        font.adjustSelectionRectForText(m_paintTextRun, selectionRect, startOffset, endOffset);
+        snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), m_paintTextRun.ltr());
     }
 
     // 2. Paint
-    auto textDecorations = lineStyle.textDecorationsInEffect();
+    auto textDecorations = m_style.textDecorationsInEffect();
     textDecorations.add(TextDecorationPainter::textDecorationsInEffectForStyle(markedText.style.textDecorationStyles));
-    TextDecorationPainter decorationPainter { context, textDecorations, m_renderer, m_textBox.isFirstLine(), font, markedText.style.textDecorationStyles };
-    decorationPainter.setTextRunIterator(LayoutIntegration::textRunFor(&m_textBox));
+    TextDecorationPainter decorationPainter { context, textDecorations, m_renderer, m_isFirstLine, font, markedText.style.textDecorationStyles };
+    decorationPainter.setTextRunIterator(m_textBox);
     decorationPainter.setWidth(snappedSelectionRect.width());
-    decorationPainter.setIsHorizontal(m_textBox.isHorizontal());
+    decorationPainter.setIsHorizontal(textBox().isHorizontal());
     if (markedText.style.textShadow) {
         decorationPainter.setTextShadow(&markedText.style.textShadow.value());
-        if (lineStyle.hasAppleColorFilter())
-            decorationPainter.setShadowColorFilter(&lineStyle.appleColorFilter());
+        if (m_style.hasAppleColorFilter())
+            decorationPainter.setShadowColorFilter(&m_style.appleColorFilter());
     }
 
     {
@@ -376,7 +386,7 @@
             if (!clipOutRect.isEmpty())
                 context.clipOut(clipOutRect);
         }
-        decorationPainter.paintTextDecoration(textRun.subRun(startOffset, endOffset - startOffset), m_textBox.textOriginFromBoxRect(snappedSelectionRect), snappedSelectionRect.location());
+        decorationPainter.paintTextDecoration(m_paintTextRun.subRun(startOffset, endOffset - startOffset), textOriginFromPaintRect(snappedSelectionRect), snappedSelectionRect.location());
     }
 
     if (isCombinedText)
@@ -386,7 +396,7 @@
 void TextBoxPainter::paintCompositionUnderlines()
 {
     for (auto& underline : m_renderer.frame().editor().customCompositionUnderlines()) {
-        if (underline.endOffset <= m_textBox.start()) {
+        if (underline.endOffset <= textBox().start()) {
             // Underline is completely before this run. This might be an underline that sits
             // before the first run we draw, or underlines that were within runs we skipped
             // due to truncation.
@@ -393,13 +403,13 @@
             continue;
         }
 
-        if (underline.startOffset >= m_textBox.end())
+        if (underline.startOffset >= textBox().end())
             break; // Underline is completely after this run, bail. A later run will paint it.
 
         // Underline intersects this run. Paint it.
         paintCompositionUnderline(underline);
 
-        if (underline.endOffset > m_textBox.end())
+        if (underline.endOffset > textBox().end())
             break; // Underline also runs into the next run. Bail now, no more marker advancement.
     }
 }
@@ -411,29 +421,38 @@
     start = logicalWidth - width - start;
 }
 
+static float textPosition(const LayoutIntegration::TextRunIterator& textBox)
+{
+    // When computing the width of a text run, RenderBlock::computeInlineDirectionPositionsForLine() doesn't include the actual offset
+    // from the containing block edge in its measurement. textPosition() should be consistent so the text are rendered in the same width.
+    if (!textBox->logicalLeft())
+        return 0;
+    return textBox->logicalLeft() - textBox->line()->contentLogicalLeft();
+}
+
 void TextBoxPainter::paintCompositionUnderline(const CompositionUnderline& underline)
 {
     float start = 0; // start of line to draw, relative to tx
-    float width = m_textBox.logicalWidth(); // how much line to draw
+    float width = textBox().logicalWidth(); // how much line to draw
     bool useWholeWidth = true;
-    unsigned paintStart = m_textBox.start();
-    unsigned paintEnd = m_textBox.end();
+    unsigned paintStart = textBox().start();
+    unsigned paintEnd = textBox().end();
     if (paintStart <= underline.startOffset) {
         paintStart = underline.startOffset;
         useWholeWidth = false;
-        start = m_renderer.width(m_textBox.start(), paintStart - m_textBox.start(), m_textBox.textPos(), m_textBox.isFirstLine());
+        start = m_renderer.width(textBox().start(), paintStart - textBox().start(), textPosition(m_textBox), m_isFirstLine);
     }
     if (paintEnd != underline.endOffset) {
         paintEnd = std::min(paintEnd, (unsigned)underline.endOffset);
         useWholeWidth = false;
     }
-    if (m_textBox.truncation()) {
-        paintEnd = std::min(paintEnd, m_textBox.start() + *m_textBox.truncation());
+    if (m_selectableRange.truncation) {
+        paintEnd = std::min(paintEnd, textBox().start() + *m_selectableRange.truncation);
         useWholeWidth = false;
     }
     if (!useWholeWidth) {
-        width = m_renderer.width(paintStart, paintEnd - paintStart, m_textBox.textPos() + start, m_textBox.isFirstLine());
-        mirrorRTLSegment(m_textBox.logicalWidth(), m_textBox.direction(), start, width);
+        width = m_renderer.width(paintStart, paintEnd - paintStart, textPosition(m_textBox) + start, m_isFirstLine);
+        mirrorRTLSegment(textBox().logicalWidth(), textBox().direction(), start, width);
     }
 
     // Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline.
@@ -440,8 +459,8 @@
     // All other marked text underlines are 1px thick.
     // If there's not enough space the underline will touch or overlap characters.
     int lineThickness = 1;
-    int baseline = m_textBox.lineStyle().fontMetrics().ascent();
-    if (underline.thick && m_textBox.logicalHeight() - baseline >= 2)
+    int baseline = m_style.fontMetrics().ascent();
+    if (underline.thick && textBox().logicalHeight() - baseline >= 2)
         lineThickness = 2;
 
     // We need to have some space between underlines of subsequent clauses, because some input methods do not use different underline styles for those.
@@ -455,12 +474,12 @@
     GraphicsContext& context = m_paintInfo.context();
     context.setStrokeColor(underlineColor);
     context.setStrokeThickness(lineThickness);
-    context.drawLineForText(FloatRect(m_paintRect.x() + start, m_paintRect.y() + m_textBox.logicalHeight() - lineThickness, width, lineThickness), m_document.printing());
+    context.drawLineForText(FloatRect(m_paintRect.x() + start, m_paintRect.y() + textBox().logicalHeight() - lineThickness, width, lineThickness), m_document.printing());
 }
 
 void TextBoxPainter::paintPlatformDocumentMarkers()
 {
-    auto markedTexts = MarkedText::collectForDocumentMarkers(m_renderer, m_textBox.selectableRange(), MarkedText::PaintPhase::Decoration);
+    auto markedTexts = MarkedText::collectForDocumentMarkers(m_renderer, m_selectableRange, MarkedText::PaintPhase::Decoration);
     for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost))
         paintPlatformDocumentMarker(markedText);
 }
@@ -471,7 +490,7 @@
     FloatRect result;
     auto markedTexts = MarkedText::collectForDocumentMarkers(textBox.renderer(), textBox.selectableRange(), MarkedText::PaintPhase::Decoration);
     for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost))
-        result = unionRect(result, calculateDocumentMarkerBounds(textBox, markedText));
+        result = unionRect(result, calculateDocumentMarkerBounds(LayoutIntegration::textRunFor(&textBox), markedText));
     return result;
 }
 
@@ -509,13 +528,12 @@
     m_paintInfo.context().drawDotsForDocumentMarker(bounds, lineStyleForMarkedTextType());
 }
 
-FloatRect TextBoxPainter::computePaintRect(const LegacyInlineTextBox& textBox, const LayoutPoint& paintOffset)
+FloatRect TextBoxPainter::computePaintRect(const LayoutPoint& paintOffset)
 {
     FloatPoint localPaintOffset(paintOffset);
 
-    if (textBox.truncation()) {
-        auto& renderer = textBox.renderer();
-        if (renderer.containingBlock()->style().isLeftToRightDirection() != textBox.isLeftToRightDirection()) {
+    if (m_selectableRange.truncation) {
+        if (m_renderer.containingBlock()->style().isLeftToRightDirection() != textBox().isLeftToRightDirection()) {
             // Make the visible fragment of text hug the edge closest to the rest of the run by moving the origin
             // at which we start drawing text.
             // e.g. In the case of LTR text truncated in an RTL Context, the correct behavior is:
@@ -524,23 +542,41 @@
             // farther to the right.
             // NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the
             // truncated string i.e.  |Hello|CBA| -> |...lo|CBA|
-            LayoutUnit widthOfVisibleText { renderer.width(textBox.start(), *textBox.truncation(), textBox.textPos(), textBox.isFirstLine()) };
-            LayoutUnit widthOfHiddenText { textBox.logicalWidth() - widthOfVisibleText };
-            LayoutSize truncationOffset(textBox.isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0_lu);
-            localPaintOffset.move(textBox.isHorizontal() ? truncationOffset : truncationOffset.transposedSize());
+            LayoutUnit widthOfVisibleText { m_renderer.width(textBox().start(), *m_selectableRange.truncation, textPosition(m_textBox), m_isFirstLine) };
+            LayoutUnit widthOfHiddenText { textBox().logicalWidth() - widthOfVisibleText };
+            LayoutSize truncationOffset(textBox().isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0_lu);
+            localPaintOffset.move(textBox().isHorizontal() ? truncationOffset : truncationOffset.transposedSize());
         }
     }
 
-    localPaintOffset.move(0, textBox.lineStyle().isHorizontalWritingMode() ? 0 : -textBox.logicalHeight());
+    localPaintOffset.move(0, m_style.isHorizontalWritingMode() ? 0 : -textBox().logicalHeight());
 
-    FloatPoint boxOrigin = textBox.locationIncludingFlipping();
+    auto locationIncludingFlipping = [&]() -> FloatPoint {
+        auto rect = textBox().rect();
+        if (!m_style.isFlippedBlocksWritingMode())
+            return rect.location();
+        auto& block = textBox().line()->containingBlock();
+        if (block.style().isHorizontalWritingMode())
+            return { rect.x(), block.height() - rect.height() - rect.y() };
+        return { block.width() - rect.width() - rect.x(), rect.y() };
+    };
+
+    FloatPoint boxOrigin = locationIncludingFlipping();
     boxOrigin.moveBy(localPaintOffset);
-    return { boxOrigin, FloatSize(textBox.logicalWidth(), textBox.logicalHeight()) };
+    return { boxOrigin, FloatSize(textBox().logicalWidth(), textBox().logicalHeight()) };
 }
 
-FloatRect TextBoxPainter::calculateDocumentMarkerBounds(const LegacyInlineTextBox& textBox, const MarkedText& markedText)
+static const FontCascade& fontCascadeFor(const RenderText& renderer, const RenderStyle& textBoxStyle)
 {
-    auto& font = textBox.lineFont();
+    if (is<RenderCombineText>(renderer))
+        return downcast<RenderCombineText>(renderer).textCombineFont();
+
+    return textBoxStyle.fontCascade();
+}
+
+FloatRect TextBoxPainter::calculateDocumentMarkerBounds(const LayoutIntegration::TextRunIterator& textBox, const MarkedText& markedText)
+{
+    auto& font = fontCascadeFor(textBox->renderer(), textBox->style());
     auto ascent = font.fontMetrics().ascent();
     auto fontSize = std::min(std::max(font.size(), 10.0f), 40.0f);
     auto y = ascent + 0.11035 * fontSize;
@@ -547,14 +583,58 @@
     auto height = 0.13247 * fontSize;
 
     // Avoid measuring the text when the entire line box is selected as an optimization.
-    if (markedText.startOffset || markedText.endOffset != textBox.selectableRange().clamp(textBox.end())) {
-        TextRun run = textBox.createTextRun();
+    if (markedText.startOffset || markedText.endOffset != textBox->selectableRange().clamp(textBox->end())) {
+        TextRun run = textBox->createTextRun();
         LayoutRect selectionRect = LayoutRect(0, y, 0, height);
-        textBox.lineFont().adjustSelectionRectForText(run, selectionRect, markedText.startOffset, markedText.endOffset);
+        font.adjustSelectionRectForText(run, selectionRect, markedText.startOffset, markedText.endOffset);
         return selectionRect;
     }
 
-    return FloatRect(0, y, textBox.logicalWidth(), height);
+    return FloatRect(0, y, textBox->logicalWidth(), height);
 }
 
+bool TextBoxPainter::computeHaveSelection() const
+{
+    if (m_isPrinting || m_paintInfo.phase == PaintPhase::TextClip)
+        return false;
+
+    return m_renderer.view().selection().highlightStateForTextBox(m_renderer, m_selectableRange) != RenderObject::HighlightState::None;
 }
+
+const RenderCombineText* TextBoxPainter::combinedText() const
+{
+    return is<RenderCombineText>(m_renderer) ? &downcast<RenderCombineText>(m_renderer) : nullptr;
+}
+
+const FontCascade& TextBoxPainter::fontCascade() const
+{
+    return fontCascadeFor(m_renderer, m_style);
+}
+
+FloatPoint TextBoxPainter::textOriginFromPaintRect(const FloatRect& paintRect) const
+{
+    FloatPoint textOrigin { paintRect.x(), paintRect.y() + fontCascade().fontMetrics().ascent() };
+    if (auto* combinedText = this->combinedText()) {
+        if (auto newOrigin = combinedText->computeTextOrigin(paintRect))
+            textOrigin = newOrigin.value();
+    }
+    if (textBox().isHorizontal())
+        textOrigin.setY(roundToDevicePixel(LayoutUnit { textOrigin.y() }, m_renderer.document().deviceScaleFactor()));
+    else
+        textOrigin.setX(roundToDevicePixel(LayoutUnit { textOrigin.x() }, m_renderer.document().deviceScaleFactor()));
+    return textOrigin;
+}
+
+const ShadowData* TextBoxPainter::debugTextShadow() const
+{
+    if (!m_renderer.settings().legacyLineLayoutVisualCoverageEnabled())
+        return nullptr;
+    if (!textBox().legacyInlineBox())
+        return nullptr;
+
+    static NeverDestroyed<ShadowData> debugTextShadow(IntPoint(0, 0), 10, 20, ShadowStyle::Normal, true, SRGBA<uint8_t> { 150, 0, 0, 190 });
+    return &debugTextShadow.get();
+}
+
+
+}

Modified: trunk/Source/WebCore/rendering/TextBoxPainter.h (282734 => 282735)


--- trunk/Source/WebCore/rendering/TextBoxPainter.h	2021-09-19 04:25:25 UTC (rev 282734)
+++ trunk/Source/WebCore/rendering/TextBoxPainter.h	2021-09-19 14:27:51 UTC (rev 282735)
@@ -25,6 +25,10 @@
 #pragma once
 
 #include "FloatRect.h"
+#include "LayoutIntegrationRunIterator.h"
+#include "RenderObject.h"
+#include "TextBoxSelectableRange.h"
+#include "TextRun.h"
 
 namespace WebCore {
 
@@ -31,7 +35,10 @@
 class Color;
 class Document;
 class LegacyInlineTextBox;
+class RenderCombineText;
+class RenderStyle;
 class RenderText;
+class ShadowData;
 struct CompositionUnderline;
 struct MarkedText;
 struct PaintInfo;
@@ -40,6 +47,7 @@
 class TextBoxPainter {
 public:
     TextBoxPainter(const LegacyInlineTextBox&, PaintInfo&, const LayoutPoint& paintOffset);
+    TextBoxPainter(const LayoutIntegration::InlineContent&, const Layout::Run&, PaintInfo&, const LayoutPoint& paintOffset);
     ~TextBoxPainter();
 
     void paint();
@@ -47,6 +55,10 @@
     static FloatRect calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox&);
 
 private:
+    TextBoxPainter(LayoutIntegration::TextRunIterator&&, PaintInfo&, const LayoutPoint& paintOffset);
+
+    auto& textBox() const { return *m_textBox; }
+
     void paintBackground();
     void paintForegroundAndDecorations();
     void paintCompositionBackground();
@@ -61,18 +73,31 @@
     void paintCompositionUnderline(const CompositionUnderline&);
     void paintPlatformDocumentMarker(const MarkedText&);
 
-    static FloatRect computePaintRect(const LegacyInlineTextBox&, const LayoutPoint& paintOffset);
-    static FloatRect calculateDocumentMarkerBounds(const LegacyInlineTextBox&, const MarkedText&);
+    static FloatRect calculateDocumentMarkerBounds(const LayoutIntegration::TextRunIterator&, const MarkedText&);
 
-    const LegacyInlineTextBox& m_textBox;
+    FloatRect computePaintRect(const LayoutPoint& paintOffset);
+    bool computeHaveSelection() const;
+    MarkedText createMarkedTextFromSelectionInBox();
+    const RenderCombineText* combinedText() const;
+    const FontCascade& fontCascade() const;
+    FloatPoint textOriginFromPaintRect(const FloatRect&) const;
+
+    const ShadowData* debugTextShadow() const;
+
+    const LayoutIntegration::TextRunIterator m_textBox;
     const RenderText& m_renderer;
     const Document& m_document;
+    const RenderStyle& m_style;
+    const TextRun m_paintTextRun;
     PaintInfo& m_paintInfo;
+    const TextBoxSelectableRange m_selectableRange;
     const FloatRect m_paintRect;
+    const bool m_isFirstLine;
     const bool m_isPrinting;
     const bool m_haveSelection;
     const bool m_containsComposition;
     const bool m_useCustomUnderlines;
+    std::optional<bool> m_emphasisMarkExistsAndIsAbove { };
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to