Title: [282311] trunk/Source/WebCore
Revision
282311
Author
[email protected]
Date
2021-09-11 09:10:13 -0700 (Sat, 11 Sep 2021)

Log Message

Move rest of the LegacyInlineTextBox painting code to TextBoxPainter
https://bugs.webkit.org/show_bug.cgi?id=230188

Reviewed by Alan Bujtas.

Move the remaining painting code.

* rendering/LegacyEllipsisBox.h:
* rendering/LegacyInlineBox.cpp:
(WebCore::LegacyInlineBox::selectionState const):
(WebCore::LegacyInlineBox::selectionState): Deleted.
* rendering/LegacyInlineBox.h:
* rendering/LegacyInlineFlowBox.cpp:
(WebCore::LegacyInlineFlowBox::selectionState const):
(WebCore::LegacyInlineFlowBox::selectionState): Deleted.
* rendering/LegacyInlineFlowBox.h:
* rendering/LegacyInlineTextBox.cpp:
(WebCore::LegacyInlineTextBox::selectionState const):
(WebCore::LegacyInlineTextBox::paint):
(WebCore::LegacyInlineTextBox::selectionState): Deleted.
(WebCore::createMarkedTextFromSelectionInBox): Deleted.
* rendering/LegacyInlineTextBox.h:
* rendering/LegacyRootInlineBox.cpp:
(WebCore::LegacyRootInlineBox::selectionState const):
(WebCore::LegacyRootInlineBox::selectionState): Deleted.
* rendering/LegacyRootInlineBox.h:
* rendering/MarkedText.cpp:
(WebCore::MarkedText::collectForHighlights):
* rendering/MarkedText.h:
* rendering/TextBoxPainter.cpp:
(WebCore::TextBoxPainter::TextBoxPainter):
(WebCore::TextBoxPainter::~TextBoxPainter):
(WebCore::TextBoxPainter::paint):
(WebCore::createMarkedTextFromSelectionInBox):
(WebCore::TextBoxPainter::paintBackground):
(WebCore::TextBoxPainter::paintForegroundAndDecorations):
(WebCore::TextBoxPainter::paintForeground):
(WebCore::TextBoxPainter::paintDecoration):
(WebCore::TextBoxPainter::paintCompositionUnderline):
(WebCore::TextBoxPainter::paintPlatformDocumentMarker):
(WebCore::TextBoxPainter::computePaintRect):
* rendering/TextBoxPainter.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (282310 => 282311)


--- trunk/Source/WebCore/ChangeLog	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/ChangeLog	2021-09-11 16:10:13 UTC (rev 282311)
@@ -1,3 +1,48 @@
+2021-09-11  Antti Koivisto  <[email protected]>
+
+        Move rest of the LegacyInlineTextBox painting code to TextBoxPainter
+        https://bugs.webkit.org/show_bug.cgi?id=230188
+
+        Reviewed by Alan Bujtas.
+
+        Move the remaining painting code.
+
+        * rendering/LegacyEllipsisBox.h:
+        * rendering/LegacyInlineBox.cpp:
+        (WebCore::LegacyInlineBox::selectionState const):
+        (WebCore::LegacyInlineBox::selectionState): Deleted.
+        * rendering/LegacyInlineBox.h:
+        * rendering/LegacyInlineFlowBox.cpp:
+        (WebCore::LegacyInlineFlowBox::selectionState const):
+        (WebCore::LegacyInlineFlowBox::selectionState): Deleted.
+        * rendering/LegacyInlineFlowBox.h:
+        * rendering/LegacyInlineTextBox.cpp:
+        (WebCore::LegacyInlineTextBox::selectionState const):
+        (WebCore::LegacyInlineTextBox::paint):
+        (WebCore::LegacyInlineTextBox::selectionState): Deleted.
+        (WebCore::createMarkedTextFromSelectionInBox): Deleted.
+        * rendering/LegacyInlineTextBox.h:
+        * rendering/LegacyRootInlineBox.cpp:
+        (WebCore::LegacyRootInlineBox::selectionState const):
+        (WebCore::LegacyRootInlineBox::selectionState): Deleted.
+        * rendering/LegacyRootInlineBox.h:
+        * rendering/MarkedText.cpp:
+        (WebCore::MarkedText::collectForHighlights):
+        * rendering/MarkedText.h:
+        * rendering/TextBoxPainter.cpp:
+        (WebCore::TextBoxPainter::TextBoxPainter):
+        (WebCore::TextBoxPainter::~TextBoxPainter):
+        (WebCore::TextBoxPainter::paint):
+        (WebCore::createMarkedTextFromSelectionInBox):
+        (WebCore::TextBoxPainter::paintBackground):
+        (WebCore::TextBoxPainter::paintForegroundAndDecorations):
+        (WebCore::TextBoxPainter::paintForeground):
+        (WebCore::TextBoxPainter::paintDecoration):
+        (WebCore::TextBoxPainter::paintCompositionUnderline):
+        (WebCore::TextBoxPainter::paintPlatformDocumentMarker):
+        (WebCore::TextBoxPainter::computePaintRect):
+        * rendering/TextBoxPainter.h:
+
 2021-09-11  Philippe Normand  <[email protected]>
 
         [GLIB] MediaSession is not enabled

Modified: trunk/Source/WebCore/rendering/LegacyEllipsisBox.h (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyEllipsisBox.h	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyEllipsisBox.h	2021-09-11 16:10:13 UTC (rev 282311)
@@ -41,7 +41,7 @@
 private:
     void paintMarkupBox(PaintInfo&, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom, const RenderStyle&);
     int height() const { return m_height; }
-    RenderObject::HighlightState selectionState() override { return m_selectionState; }
+    RenderObject::HighlightState selectionState() const override { return m_selectionState; }
     void paintSelection(GraphicsContext&, const LayoutPoint&, const RenderStyle&, const FontCascade&);
     LegacyInlineBox* markupBox() const;
 

Modified: trunk/Source/WebCore/rendering/LegacyInlineBox.cpp (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyInlineBox.cpp	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyInlineBox.cpp	2021-09-11 16:10:13 UTC (rev 282311)
@@ -245,7 +245,7 @@
     return leaf;
 }
 
-RenderObject::HighlightState LegacyInlineBox::selectionState()
+RenderObject::HighlightState LegacyInlineBox::selectionState() const
 {
     return renderer().selectionState();
 }

Modified: trunk/Source/WebCore/rendering/LegacyInlineBox.h (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyInlineBox.h	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyInlineBox.h	2021-09-11 16:10:13 UTC (rev 282311)
@@ -219,7 +219,7 @@
 
     WEBCORE_EXPORT virtual void dirtyLineBoxes();
     
-    WEBCORE_EXPORT virtual RenderObject::HighlightState selectionState();
+    WEBCORE_EXPORT virtual RenderObject::HighlightState selectionState() const;
 
     WEBCORE_EXPORT virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const;
     // visibleLeftEdge, visibleRightEdge are in the parent's coordinate system.

Modified: trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp	2021-09-11 16:10:13 UTC (rev 282311)
@@ -1456,7 +1456,7 @@
     return leaf;
 }
 
-RenderObject::HighlightState LegacyInlineFlowBox::selectionState()
+RenderObject::HighlightState LegacyInlineFlowBox::selectionState() const
 {
     return RenderObject::HighlightState::None;
 }

Modified: trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h	2021-09-11 16:10:13 UTC (rev 282311)
@@ -203,7 +203,7 @@
     
     void removeChild(LegacyInlineBox* child);
 
-    RenderObject::HighlightState selectionState() override;
+    RenderObject::HighlightState selectionState() const override;
 
     bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const final;
     float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool&) override;

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-09-11 16:10:13 UTC (rev 282311)
@@ -159,7 +159,7 @@
     return selectableRange().intersects(startPosition, endPosition);
 }
 
-RenderObject::HighlightState LegacyInlineTextBox::selectionState()
+RenderObject::HighlightState LegacyInlineTextBox::selectionState() const
 {
     auto state = renderer().view().selection().highlightStateForTextBox(renderer(), selectableRange());
     
@@ -404,14 +404,6 @@
     return isAbove;
 }
 
-static MarkedText createMarkedTextFromSelectionInBox(const LegacyInlineTextBox& box)
-{
-    auto [selectionStart, selectionEnd] = box.selectionStartEnd();
-    if (selectionStart < selectionEnd)
-        return { selectionStart, selectionEnd, MarkedText::Selection };
-    return { };
-}
-
 void LegacyInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
 {
     if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible
@@ -427,187 +419,12 @@
     
     LayoutUnit paintEnd = isHorizontal() ? paintInfo.rect.maxX() : paintInfo.rect.maxY();
     LayoutUnit paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect.y();
-    
-    FloatPoint localPaintOffset(paintOffset);
-    
+
     if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart)
         return;
 
-    bool isPrinting = renderer().document().printing();
-    
-    // Determine whether or not we're selected.
-    bool haveSelection = !isPrinting && paintInfo.phase != PaintPhase::TextClip && selectionState() != RenderObject::HighlightState::None;
-    if (!haveSelection && paintInfo.phase == PaintPhase::Selection) {
-        // When only painting the selection, don't bother to paint if there is none.
-        return;
-    }
-
-    if (m_truncation != cNoTruncation) {
-        if (renderer().containingBlock()->style().isLeftToRightDirection() != 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:
-            // |Hello|CBA| -> |...He|CBA|
-            // In order to draw the fragment "He" aligned to the right edge of it's box, we need to start drawing
-            // 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(m_start, m_truncation, textPos(), isFirstLine()) };
-            LayoutUnit widthOfHiddenText { logicalWidth() - widthOfVisibleText };
-            LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0_lu);
-            localPaintOffset.move(isHorizontal() ? truncationOffset : truncationOffset.transposedSize());
-        }
-    }
-
-    const RenderStyle& lineStyle = this->lineStyle();
-    
-    localPaintOffset.move(0, lineStyle.isHorizontalWritingMode() ? 0 : -logicalHeight());
-
-    FloatPoint boxOrigin = locationIncludingFlipping();
-    boxOrigin.moveBy(localPaintOffset);
-    FloatRect boxRect(boxOrigin, FloatSize(logicalWidth(), logicalHeight()));
-
-    if (paintInfo.phase == PaintPhase::EventRegion) {
-        if (visibleToHitTesting())
-            paintInfo.eventRegionContext->unite(enclosingIntRect(boxRect), renderer().style());
-        return;
-    }
-
-    TextBoxPainter textBoxPainter(*this, paintInfo, boxRect);
-
-    // Determine whether or not we have composition underlines to draw.
-    bool containsComposition = renderer().textNode() && renderer().frame().editor().compositionNode() == renderer().textNode();
-    bool useCustomUnderlines = containsComposition && renderer().frame().editor().compositionUsesCustomUnderlines();
-
-    // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection
-    // and composition underlines.
-    if (paintInfo.phase != PaintPhase::Selection && paintInfo.phase != PaintPhase::TextClip && !isPrinting) {
-        if (containsComposition && !useCustomUnderlines)
-            textBoxPainter.paintCompositionBackground();
-
-        auto selectableRange = this->selectableRange();
-
-        Vector<MarkedText> markedTexts;
-        markedTexts.appendVector(MarkedText::collectForDocumentMarkers(renderer(), selectableRange, MarkedText::PaintPhase::Background));
-        markedTexts.appendVector(MarkedText::collectForHighlights(renderer(), parent()->renderer(), selectableRange, MarkedText::PaintPhase::Background));
-
-#if ENABLE(TEXT_SELECTION)
-        GraphicsContext& context = paintInfo.context();
-        if (haveSelection && !useCustomUnderlines && !context.paintingDisabled()) {
-            auto selectionMarkedText = createMarkedTextFromSelectionInBox(*this);
-            if (!selectionMarkedText.isEmpty())
-                markedTexts.append(WTFMove(selectionMarkedText));
-        }
-#endif
-        auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, renderer(), isFirstLine(), paintInfo);
-
-        // Coalesce styles of adjacent marked texts to minimize the number of drawing commands.
-        auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualBackground(styledMarkedTexts);
-
-        for (auto& markedText : coalescedStyledMarkedTexts)
-            textBoxPainter.paintBackground(markedText);
-    }
-
-    // FIXME: Right now, LegacyInlineTextBoxes never call addRelevantUnpaintedObject() even though they might
-    // legitimately be unpainted if they are waiting on a slow-loading web font. We should fix that, and
-    // when we do, we will have to account for the fact the LegacyInlineTextBoxes do not always have unique
-    // renderers and Page currently relies on each unpainted object having a unique renderer.
-    if (paintInfo.phase == PaintPhase::Foreground)
-        renderer().page().addRelevantRepaintedObject(&renderer(), IntRect(boxOrigin.x(), boxOrigin.y(), logicalWidth(), logicalHeight()));
-
-    if (paintInfo.phase == PaintPhase::Foreground)
-        textBoxPainter.paintPlatformDocumentMarkers();
-
-    // 2. Now paint the foreground, including text and decorations like underline/overline (in quirks mode only).
-    bool shouldPaintSelectionForeground = haveSelection && !useCustomUnderlines;
-    Vector<MarkedText> markedTexts;
-    if (paintInfo.phase != PaintPhase::Selection) {
-        auto selectableRange = this->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_start), selectableRange.clamp(end()), MarkedText::Unmarked });
-        
-        if (!isPrinting) {
-            markedTexts.appendVector(MarkedText::collectForDocumentMarkers(renderer(), selectableRange, MarkedText::PaintPhase::Foreground));
-            markedTexts.appendVector(MarkedText::collectForHighlights(renderer(), parent()->renderer(), selectableRange, MarkedText::PaintPhase::Foreground));
-
-            bool shouldPaintDraggedContent = !(paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection));
-            if (shouldPaintDraggedContent) {
-                auto markedTextsForDraggedContent = MarkedText::collectForDraggedContent(renderer(), selectableRange);
-                if (!markedTextsForDraggedContent.isEmpty()) {
-                    shouldPaintSelectionForeground = false;
-                    markedTexts.appendVector(markedTextsForDraggedContent);
-                }
-            }
-        }
-    }
-    // The selection marked text acts as a placeholder when computing the marked texts for the gaps...
-    if (shouldPaintSelectionForeground) {
-        ASSERT(!isPrinting);
-        auto selectionMarkedText = createMarkedTextFromSelectionInBox(*this);
-        if (!selectionMarkedText.isEmpty())
-            markedTexts.append(WTFMove(selectionMarkedText));
-    }
-
-    auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, renderer(), isFirstLine(), paintInfo);
-
-    // ... now remove the selection marked text if we are excluding selection.
-    if (!isPrinting && paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection)) {
-        styledMarkedTexts.removeAllMatching([] (const StyledMarkedText& markedText) {
-            return markedText.type == MarkedText::Selection;
-        });
-    }
-
-    // Coalesce styles of adjacent marked texts to minimize the number of drawing commands.
-    auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualForeground(styledMarkedTexts);
-
-    for (auto& markedText : coalescedStyledMarkedTexts)
-        textBoxPainter.paintForeground(markedText);
-
-    // Paint decorations
-    auto textDecorations = lineStyle.textDecorationsInEffect();
-    bool highlightDecorations = !MarkedText::collectForHighlights(renderer(), parent()->renderer(), selectableRange(), MarkedText::PaintPhase::Decoration).isEmpty();
-    bool lineDecorations = !textDecorations.isEmpty();
-    if ((lineDecorations || highlightDecorations) && paintInfo.phase != PaintPhase::Selection) {
-        TextRun textRun = createTextRun();
-        unsigned length = textRun.length();
-        if (m_truncation != cNoTruncation)
-            length = m_truncation;
-        unsigned selectionStart = 0;
-        unsigned selectionEnd = 0;
-        if (haveSelection)
-            std::tie(selectionStart, selectionEnd) = selectionStartEnd();
-
-        FloatRect textDecorationSelectionClipOutRect;
-        if ((paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection)) && selectionStart < selectionEnd && selectionEnd <= length) {
-            textDecorationSelectionClipOutRect = logicalOverflowRect();
-            textDecorationSelectionClipOutRect.moveBy(localPaintOffset);
-            float logicalWidthBeforeRange;
-            float logicalWidthAfterRange;
-            float logicalSelectionWidth = lineFont().widthOfTextRange(textRun, selectionStart, selectionEnd, nullptr, &logicalWidthBeforeRange, &logicalWidthAfterRange);
-            // FIXME: Do we need to handle vertical bottom to top text?
-            if (!isHorizontal()) {
-                textDecorationSelectionClipOutRect.move(0, logicalWidthBeforeRange);
-                textDecorationSelectionClipOutRect.setHeight(logicalSelectionWidth);
-            } else if (direction() == TextDirection::RTL) {
-                textDecorationSelectionClipOutRect.move(logicalWidthAfterRange, 0);
-                textDecorationSelectionClipOutRect.setWidth(logicalSelectionWidth);
-            } else {
-                textDecorationSelectionClipOutRect.move(logicalWidthBeforeRange, 0);
-                textDecorationSelectionClipOutRect.setWidth(logicalSelectionWidth);
-            }
-        }
-
-        // Coalesce styles of adjacent marked texts to minimize the number of drawing commands.
-        auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualDecorations(styledMarkedTexts);
-
-        for (auto& markedText : coalescedStyledMarkedTexts)
-            textBoxPainter.paintDecoration(markedText, textDecorationSelectionClipOutRect);
-    }
-
-    // 3. Paint fancy decorations, including composition underlines and platform-specific underlines for spelling errors, grammar errors, et cetera.
-    if (paintInfo.phase == PaintPhase::Foreground && useCustomUnderlines)
-        textBoxPainter.paintCompositionUnderlines();
+    TextBoxPainter textBoxPainter(*this, paintInfo, paintOffset);
+    textBoxPainter.paint();
 }
 
 TextBoxSelectableRange LegacyInlineTextBox::selectableRange() const

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.h (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-09-11 16:10:13 UTC (rev 282311)
@@ -128,7 +128,7 @@
     void attachLine() final;
     
 public:
-    RenderObject::HighlightState selectionState() final;
+    RenderObject::HighlightState selectionState() const final;
 
 private:
     void clearTruncation() final { m_truncation = cNoTruncation; }

Modified: trunk/Source/WebCore/rendering/LegacyRootInlineBox.cpp (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyRootInlineBox.cpp	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyRootInlineBox.cpp	2021-09-11 16:10:13 UTC (rev 282311)
@@ -482,7 +482,7 @@
     return result;
 }
 
-RenderObject::HighlightState LegacyRootInlineBox::selectionState()
+RenderObject::HighlightState LegacyRootInlineBox::selectionState() const
 {
     // Walk over all of the selected boxes.
     RenderObject::HighlightState state = RenderObject::HighlightState::None;

Modified: trunk/Source/WebCore/rendering/LegacyRootInlineBox.h (282310 => 282311)


--- trunk/Source/WebCore/rendering/LegacyRootInlineBox.h	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/LegacyRootInlineBox.h	2021-09-11 16:10:13 UTC (rev 282311)
@@ -126,7 +126,7 @@
     void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) override;
 
-    RenderObject::HighlightState selectionState() final;
+    RenderObject::HighlightState selectionState() const final;
     LegacyInlineBox* firstSelectedBox();
     LegacyInlineBox* lastSelectedBox();
 

Modified: trunk/Source/WebCore/rendering/MarkedText.cpp (282310 => 282311)


--- trunk/Source/WebCore/rendering/MarkedText.cpp	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/MarkedText.cpp	2021-09-11 16:10:13 UTC (rev 282311)
@@ -104,11 +104,12 @@
     return result;
 }
 
-Vector<MarkedText> MarkedText::collectForHighlights(RenderText& renderer, RenderBoxModelObject& parentRenderer, const TextBoxSelectableRange& selectableRange, PaintPhase phase)
+Vector<MarkedText> MarkedText::collectForHighlights(const RenderText& renderer, const TextBoxSelectableRange& selectableRange, PaintPhase phase)
 {
     Vector<MarkedText> markedTexts;
     HighlightData highlightData;
     if (RuntimeEnabledFeatures::sharedFeatures().highlightAPIEnabled()) {
+        auto& parentRenderer = *renderer.parent();
         auto& parentStyle = parentRenderer.style();
         if (auto highlightRegister = renderer.document().highlightRegisterIfExists()) {
             for (auto& highlight : highlightRegister->map()) {
@@ -147,7 +148,7 @@
     return markedTexts;
 }
 
-Vector<MarkedText> MarkedText::collectForDocumentMarkers(RenderText& renderer, const TextBoxSelectableRange& selectableRange, PaintPhase phase)
+Vector<MarkedText> MarkedText::collectForDocumentMarkers(const RenderText& renderer, const TextBoxSelectableRange& selectableRange, PaintPhase phase)
 {
     if (!renderer.textNode())
         return { };
@@ -252,7 +253,7 @@
     return markedTexts;
 }
 
-Vector<MarkedText> MarkedText::collectForDraggedContent(RenderText& renderer, const TextBoxSelectableRange& selectableRange)
+Vector<MarkedText> MarkedText::collectForDraggedContent(const RenderText& renderer, const TextBoxSelectableRange& selectableRange)
 {
     auto draggedContentRanges = renderer.draggedContentRangesBetweenOffsets(selectableRange.start, selectableRange.start + selectableRange.length);
 

Modified: trunk/Source/WebCore/rendering/MarkedText.h (282310 => 282311)


--- trunk/Source/WebCore/rendering/MarkedText.h	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/MarkedText.h	2021-09-11 16:10:13 UTC (rev 282311)
@@ -82,9 +82,9 @@
 
     WEBCORE_EXPORT static Vector<MarkedText> subdivide(const Vector<MarkedText>&, OverlapStrategy = OverlapStrategy::None);
 
-    static Vector<MarkedText> collectForDocumentMarkers(RenderText&, const TextBoxSelectableRange&, PaintPhase);
-    static Vector<MarkedText> collectForHighlights(RenderText&, RenderBoxModelObject& parentRenderer, const TextBoxSelectableRange&, PaintPhase);
-    static Vector<MarkedText> collectForDraggedContent(RenderText&, const TextBoxSelectableRange&);
+    static Vector<MarkedText> collectForDocumentMarkers(const RenderText&, const TextBoxSelectableRange&, PaintPhase);
+    static Vector<MarkedText> collectForHighlights(const RenderText&, const TextBoxSelectableRange&, PaintPhase);
+    static Vector<MarkedText> collectForDraggedContent(const RenderText&, const TextBoxSelectableRange&);
 };
 
 }

Modified: trunk/Source/WebCore/rendering/TextBoxPainter.cpp (282310 => 282311)


--- trunk/Source/WebCore/rendering/TextBoxPainter.cpp	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/TextBoxPainter.cpp	2021-09-11 16:10:13 UTC (rev 282311)
@@ -30,6 +30,7 @@
 #include "GraphicsContext.h"
 #include "LegacyInlineTextBox.h"
 #include "PaintInfo.h"
+#include "RenderText.h"
 #include "StyledMarkedText.h"
 #include "TextPaintStyle.h"
 #include "TextPainter.h"
@@ -36,28 +37,186 @@
 
 namespace WebCore {
 
-TextBoxPainter::TextBoxPainter(const LegacyInlineTextBox& textBox, PaintInfo& paintInfo, const FloatRect& boxRect)
+TextBoxPainter::TextBoxPainter(const LegacyInlineTextBox& textBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     : m_textBox(textBox)
+    , m_renderer(textBox.renderer())
+    , m_document(m_renderer.document())
     , m_paintInfo(paintInfo)
-    , m_boxRect(boxRect)
+    , m_paintRect(computePaintRect(textBox, paintOffset))
+    , m_isPrinting(m_document.printing())
+    , m_haveSelection(!m_isPrinting && m_paintInfo.phase != PaintPhase::TextClip && m_textBox.selectionState() != RenderObject::HighlightState::None)
+    , m_containsComposition(m_renderer.textNode() && m_renderer.frame().editor().compositionNode() == m_renderer.textNode())
+    , m_useCustomUnderlines(m_containsComposition && m_renderer.frame().editor().compositionUsesCustomUnderlines())
 {
-    bool shouldRotate = !m_textBox.isHorizontal() && !m_textBox.combinedText();
-    if (shouldRotate)
-        m_paintInfo.context().concatCTM(rotation(m_boxRect, Clockwise));
+    ASSERT(paintInfo.phase == PaintPhase::Foreground || paintInfo.phase == PaintPhase::Selection || paintInfo.phase == PaintPhase::TextClip || paintInfo.phase == PaintPhase::EventRegion);
 }
 
 TextBoxPainter::~TextBoxPainter()
 {
+}
+
+void TextBoxPainter::paint()
+{
+    if (m_paintInfo.phase == PaintPhase::Selection && !m_haveSelection)
+        return;
+
+    if (m_paintInfo.phase == PaintPhase::EventRegion) {
+        if (m_textBox.visibleToHitTesting())
+            m_paintInfo.eventRegionContext->unite(enclosingIntRect(m_paintRect), m_renderer.style());
+        return;
+    }
+
     bool shouldRotate = !m_textBox.isHorizontal() && !m_textBox.combinedText();
     if (shouldRotate)
-        m_paintInfo.context().concatCTM(rotation(m_boxRect, Counterclockwise));
+        m_paintInfo.context().concatCTM(rotation(m_paintRect, Clockwise));
+
+    if (m_paintInfo.phase == PaintPhase::Foreground) {
+        if (!m_isPrinting)
+            paintBackground();
+
+        paintPlatformDocumentMarkers();
+    }
+
+    paintForegroundAndDecorations();
+
+    if (m_paintInfo.phase == PaintPhase::Foreground) {
+        if (m_useCustomUnderlines)
+            paintCompositionUnderlines();
+
+        m_renderer.page().addRelevantRepaintedObject(const_cast<RenderText*>(&m_renderer), enclosingLayoutRect(m_paintRect));
+    }
+
+    if (shouldRotate)
+        m_paintInfo.context().concatCTM(rotation(m_paintRect, Counterclockwise));
 }
 
+static MarkedText createMarkedTextFromSelectionInBox(const LegacyInlineTextBox& box)
+{
+    auto [selectionStart, selectionEnd] = box.selectionStartEnd();
+    if (selectionStart < selectionEnd)
+        return { selectionStart, selectionEnd, MarkedText::Selection };
+    return { };
+}
+
+void TextBoxPainter::paintBackground()
+{
+    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));
+
+#if ENABLE(TEXT_SELECTION)
+    if (m_haveSelection && !m_useCustomUnderlines && !m_paintInfo.context().paintingDisabled()) {
+        auto selectionMarkedText = createMarkedTextFromSelectionInBox(m_textBox);
+        if (!selectionMarkedText.isEmpty())
+            markedTexts.append(WTFMove(selectionMarkedText));
+    }
+#endif
+    auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, m_renderer, m_textBox.isFirstLine(), m_paintInfo);
+
+    // Coalesce styles of adjacent marked texts to minimize the number of drawing commands.
+    auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualBackground(styledMarkedTexts);
+
+    for (auto& markedText : coalescedStyledMarkedTexts)
+        paintBackground(markedText);
+}
+
+void TextBoxPainter::paintForegroundAndDecorations()
+{
+    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 });
+
+        if (!m_isPrinting) {
+            markedTexts.appendVector(MarkedText::collectForDocumentMarkers(m_renderer, selectableRange, MarkedText::PaintPhase::Foreground));
+            markedTexts.appendVector(MarkedText::collectForHighlights(m_renderer, selectableRange, MarkedText::PaintPhase::Foreground));
+
+            bool shouldPaintDraggedContent = !(m_paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection));
+            if (shouldPaintDraggedContent) {
+                auto markedTextsForDraggedContent = MarkedText::collectForDraggedContent(m_renderer, selectableRange);
+                if (!markedTextsForDraggedContent.isEmpty()) {
+                    shouldPaintSelectionForeground = false;
+                    markedTexts.appendVector(markedTextsForDraggedContent);
+                }
+            }
+        }
+    }
+    // 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);
+        if (!selectionMarkedText.isEmpty())
+            markedTexts.append(WTFMove(selectionMarkedText));
+    }
+
+    auto styledMarkedTexts = StyledMarkedText::subdivideAndResolve(markedTexts, m_renderer, m_textBox.isFirstLine(), m_paintInfo);
+
+    // ... now remove the selection marked text if we are excluding selection.
+    if (!m_isPrinting && m_paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection)) {
+        styledMarkedTexts.removeAllMatching([] (const StyledMarkedText& markedText) {
+            return markedText.type == MarkedText::Selection;
+        });
+    }
+
+    // Coalesce styles of adjacent marked texts to minimize the number of drawing commands.
+    auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualForeground(styledMarkedTexts);
+
+    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();
+    bool lineDecorations = !textDecorations.isEmpty();
+    if ((lineDecorations || highlightDecorations) && m_paintInfo.phase != PaintPhase::Selection) {
+        TextRun textRun = m_textBox.createTextRun();
+        unsigned length = textRun.length();
+        if (m_textBox.truncation() != cNoTruncation)
+            length = m_textBox.truncation();
+        unsigned selectionStart = 0;
+        unsigned selectionEnd = 0;
+        if (m_haveSelection)
+            std::tie(selectionStart, selectionEnd) = m_textBox.selectionStartEnd();
+
+        FloatRect textDecorationSelectionClipOutRect;
+        if ((m_paintInfo.paintBehavior.contains(PaintBehavior::ExcludeSelection)) && selectionStart < selectionEnd && selectionEnd <= length) {
+            textDecorationSelectionClipOutRect = m_paintRect;
+            float logicalWidthBeforeRange;
+            float logicalWidthAfterRange;
+            float logicalSelectionWidth = m_textBox.lineFont().widthOfTextRange(textRun, selectionStart, selectionEnd, nullptr, &logicalWidthBeforeRange, &logicalWidthAfterRange);
+            // FIXME: Do we need to handle vertical bottom to top text?
+            if (!m_textBox.isHorizontal()) {
+                textDecorationSelectionClipOutRect.move(0, logicalWidthBeforeRange);
+                textDecorationSelectionClipOutRect.setHeight(logicalSelectionWidth);
+            } else if (m_textBox.direction() == TextDirection::RTL) {
+                textDecorationSelectionClipOutRect.move(logicalWidthAfterRange, 0);
+                textDecorationSelectionClipOutRect.setWidth(logicalSelectionWidth);
+            } else {
+                textDecorationSelectionClipOutRect.move(logicalWidthBeforeRange, 0);
+                textDecorationSelectionClipOutRect.setWidth(logicalSelectionWidth);
+            }
+        }
+
+        // Coalesce styles of adjacent marked texts to minimize the number of drawing commands.
+        auto coalescedStyledMarkedTexts = StyledMarkedText::coalesceAdjacentWithEqualDecorations(styledMarkedTexts);
+
+        for (auto& markedText : coalescedStyledMarkedTexts)
+            paintDecoration(markedText, textDecorationSelectionClipOutRect);
+    }
+}
+
 void TextBoxPainter::paintCompositionBackground()
 {
     auto selectableRange = m_textBox.selectableRange();
 
-    auto& editor = m_textBox.renderer().frame().editor();
+    auto& editor = m_renderer.frame().editor();
 
     if (!editor.compositionUsesCustomHighlights()) {
         auto [clampedStart, clampedEnd] = selectableRange.clamp(editor.compositionStart(), editor.compositionEnd());
@@ -106,14 +265,14 @@
 
     // 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_textBox.renderer().style().isFlippedLinesWritingMode() ? selectionBottom - m_textBox.logicalBottom() : m_textBox.logicalTop() - selectionTop };
+    LayoutUnit deltaY { m_renderer.style().isFlippedLinesWritingMode() ? selectionBottom - m_textBox.logicalBottom() : m_textBox.logicalTop() - selectionTop };
     LayoutUnit selectionHeight = std::max<LayoutUnit>(0, selectionBottom - selectionTop);
 
-    LayoutRect selectionRect { LayoutUnit(m_boxRect.x()), LayoutUnit(m_boxRect.y() - deltaY), LayoutUnit(m_textBox.logicalWidth()), selectionHeight };
+    LayoutRect selectionRect { LayoutUnit(m_paintRect.x()), LayoutUnit(m_paintRect.y() - deltaY), LayoutUnit(m_textBox.logicalWidth()), selectionHeight };
     m_textBox.lineFont().adjustSelectionRectForText(textRun, selectionRect, startOffset, endOffset);
 
     // FIXME: Support painting combined text. See <https://bugs.webkit.org/show_bug.cgi?id=180993>.
-    auto backgroundRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_textBox.renderer().document().deviceScaleFactor(), textRun.ltr());
+    auto backgroundRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), textRun.ltr());
     if (backgroundStyle == BackgroundStyle::Rounded) {
         backgroundRect.expand(-1, -1);
         backgroundRect.move(0.5, 0.5);
@@ -161,7 +320,7 @@
         context.setAlpha(markedText.style.alpha);
     }
     // TextPainter wants the box rectangle and text origin of the entire line box.
-    textPainter.paintRange(textRun, m_boxRect, m_textBox.textOriginFromBoxRect(m_boxRect), markedText.startOffset, markedText.endOffset);
+    textPainter.paintRange(textRun, m_paintRect, m_textBox.textOriginFromBoxRect(m_paintRect), markedText.startOffset, markedText.endOffset);
 }
 
 void TextBoxPainter::paintDecoration(const StyledMarkedText& markedText, const FloatRect& clipOutRect)
@@ -177,7 +336,7 @@
 
     bool isCombinedText = m_textBox.combinedText();
     if (isCombinedText)
-        context.concatCTM(rotation(m_boxRect, Clockwise));
+        context.concatCTM(rotation(m_paintRect, Clockwise));
 
     // 1. Compute text selection
     unsigned startOffset = markedText.startOffset;
@@ -190,17 +349,17 @@
     TextRun textRun = m_textBox.createTextRun();
 
     // Avoid measuring the text when the entire line box is selected as an optimization.
-    FloatRect snappedSelectionRect = m_boxRect;
+    FloatRect snappedSelectionRect = m_paintRect;
     if (startOffset || endOffset != textRun.length()) {
-        LayoutRect selectionRect = { m_boxRect.x(), m_boxRect.y(), m_boxRect.width(), m_boxRect.height() };
+        LayoutRect selectionRect = { m_paintRect.x(), m_paintRect.y(), m_paintRect.width(), m_paintRect.height() };
         font.adjustSelectionRectForText(textRun, selectionRect, startOffset, endOffset);
-        snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_textBox.renderer().document().deviceScaleFactor(), textRun.ltr());
+        snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, m_document.deviceScaleFactor(), textRun.ltr());
     }
 
     // 2. Paint
     auto textDecorations = lineStyle.textDecorationsInEffect();
     textDecorations.add(TextDecorationPainter::textDecorationsInEffectForStyle(markedText.style.textDecorationStyles));
-    TextDecorationPainter decorationPainter { context, textDecorations, m_textBox.renderer(), m_textBox.isFirstLine(), font, markedText.style.textDecorationStyles };
+    TextDecorationPainter decorationPainter { context, textDecorations, m_renderer, m_textBox.isFirstLine(), font, markedText.style.textDecorationStyles };
     decorationPainter.setTextRunIterator(LayoutIntegration::textRunFor(&m_textBox));
     decorationPainter.setWidth(snappedSelectionRect.width());
     decorationPainter.setIsHorizontal(m_textBox.isHorizontal());
@@ -224,7 +383,7 @@
     }
 
     if (isCombinedText)
-        context.concatCTM(rotation(m_boxRect, Counterclockwise));
+        context.concatCTM(rotation(m_paintRect, Counterclockwise));
 }
 
 void TextBoxPainter::paintCompositionUnderlines()
@@ -232,7 +391,7 @@
     if (m_textBox.truncation() == cFullTruncation)
         return;
 
-    for (auto& underline : m_textBox.renderer().frame().editor().customCompositionUnderlines()) {
+    for (auto& underline : m_renderer.frame().editor().customCompositionUnderlines()) {
         if (underline.endOffset <= m_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
@@ -260,8 +419,6 @@
 
 void TextBoxPainter::paintCompositionUnderline(const CompositionUnderline& underline)
 {
-    auto& renderer = m_textBox.renderer();
-
     float start = 0; // start of line to draw, relative to tx
     float width = m_textBox.logicalWidth(); // how much line to draw
     bool useWholeWidth = true;
@@ -270,7 +427,7 @@
     if (paintStart <= underline.startOffset) {
         paintStart = underline.startOffset;
         useWholeWidth = false;
-        start = renderer.width(m_textBox.start(), paintStart - m_textBox.start(), m_textBox.textPos(), m_textBox.isFirstLine());
+        start = m_renderer.width(m_textBox.start(), paintStart - m_textBox.start(), m_textBox.textPos(), m_textBox.isFirstLine());
     }
     if (paintEnd != underline.endOffset) {
         paintEnd = std::min(paintEnd, (unsigned)underline.endOffset);
@@ -281,7 +438,7 @@
         useWholeWidth = false;
     }
     if (!useWholeWidth) {
-        width = renderer.width(paintStart, paintEnd - paintStart, m_textBox.textPos() + start, m_textBox.isFirstLine());
+        width = m_renderer.width(paintStart, paintEnd - paintStart, m_textBox.textPos() + start, m_textBox.isFirstLine());
         mirrorRTLSegment(m_textBox.logicalWidth(), m_textBox.direction(), start, width);
     }
 
@@ -298,16 +455,18 @@
     start += 1;
     width -= 2;
 
+    auto& style = m_renderer.style();
+    Color underlineColor = underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? style.visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor) : style.colorByApplyingColorFilter(underline.color);
+
     GraphicsContext& context = m_paintInfo.context();
-    Color underlineColor = underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? renderer.style().visitedDependentColorWithColorFilter(CSSPropertyWebkitTextFillColor) : renderer.style().colorByApplyingColorFilter(underline.color);
     context.setStrokeColor(underlineColor);
     context.setStrokeThickness(lineThickness);
-    context.drawLineForText(FloatRect(m_boxRect.x() + start, m_boxRect.y() + m_textBox.logicalHeight() - lineThickness, width, lineThickness), renderer.document().printing());
+    context.drawLineForText(FloatRect(m_paintRect.x() + start, m_paintRect.y() + m_textBox.logicalHeight() - lineThickness, width, lineThickness), m_document.printing());
 }
 
 void TextBoxPainter::paintPlatformDocumentMarkers()
 {
-    auto markedTexts = MarkedText::collectForDocumentMarkers(m_textBox.renderer(), m_textBox.selectableRange(), MarkedText::PaintPhase::Decoration);
+    auto markedTexts = MarkedText::collectForDocumentMarkers(m_renderer, m_textBox.selectableRange(), MarkedText::PaintPhase::Decoration);
     for (auto& markedText : MarkedText::subdivide(markedTexts, MarkedText::OverlapStrategy::Frontmost))
         paintPlatformDocumentMarker(markedText);
 }
@@ -325,7 +484,7 @@
 void TextBoxPainter::paintPlatformDocumentMarker(const MarkedText& markedText)
 {
     // Never print spelling/grammar markers (5327887)
-    if (m_textBox.renderer().document().printing())
+    if (m_document.printing())
         return;
 
     if (m_textBox.truncation() == cFullTruncation)
@@ -334,7 +493,7 @@
     auto bounds = calculateDocumentMarkerBounds(m_textBox, markedText);
 
     auto lineStyleForMarkedTextType = [&]() -> DocumentMarkerLineStyle {
-        bool shouldUseDarkAppearance = m_textBox.renderer().useDarkAppearance();
+        bool shouldUseDarkAppearance = m_renderer.useDarkAppearance();
         switch (markedText.type) {
         case MarkedText::SpellingError:
             return { DocumentMarkerLineStyle::Mode::Spelling, shouldUseDarkAppearance };
@@ -355,10 +514,39 @@
         }
     };
 
-    bounds.moveBy(m_boxRect.location());
+    bounds.moveBy(m_paintRect.location());
     m_paintInfo.context().drawDotsForDocumentMarker(bounds, lineStyleForMarkedTextType());
 }
 
+FloatRect TextBoxPainter::computePaintRect(const LegacyInlineTextBox& textBox, const LayoutPoint& paintOffset)
+{
+    FloatPoint localPaintOffset(paintOffset);
+
+    if (textBox.truncation() != cNoTruncation) {
+        auto& renderer = textBox.renderer();
+        if (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:
+            // |Hello|CBA| -> |...He|CBA|
+            // In order to draw the fragment "He" aligned to the right edge of it's box, we need to start drawing
+            // 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());
+        }
+    }
+
+    localPaintOffset.move(0, textBox.lineStyle().isHorizontalWritingMode() ? 0 : -textBox.logicalHeight());
+
+    FloatPoint boxOrigin = textBox.locationIncludingFlipping();
+    boxOrigin.moveBy(localPaintOffset);
+    return { boxOrigin, FloatSize(textBox.logicalWidth(), textBox.logicalHeight()) };
+}
+
 FloatRect TextBoxPainter::calculateDocumentMarkerBounds(const LegacyInlineTextBox& textBox, const MarkedText& markedText)
 {
     auto& font = textBox.lineFont();

Modified: trunk/Source/WebCore/rendering/TextBoxPainter.h (282310 => 282311)


--- trunk/Source/WebCore/rendering/TextBoxPainter.h	2021-09-11 14:59:45 UTC (rev 282310)
+++ trunk/Source/WebCore/rendering/TextBoxPainter.h	2021-09-11 16:10:13 UTC (rev 282311)
@@ -29,7 +29,9 @@
 namespace WebCore {
 
 class Color;
+class Document;
 class LegacyInlineTextBox;
+class RenderText;
 struct CompositionUnderline;
 struct MarkedText;
 struct PaintInfo;
@@ -37,29 +39,40 @@
 
 class TextBoxPainter {
 public:
-    TextBoxPainter(const LegacyInlineTextBox&, PaintInfo&, const FloatRect& boxRect);
+    TextBoxPainter(const LegacyInlineTextBox&, PaintInfo&, const LayoutPoint& paintOffset);
     ~TextBoxPainter();
 
+    void paint();
+
+    static FloatRect calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox&);
+
+private:
+    void paintBackground();
+    void paintForegroundAndDecorations();
     void paintCompositionBackground();
-    void paintBackground(const StyledMarkedText&);
-    void paintForeground(const StyledMarkedText&);
-    void paintDecoration(const StyledMarkedText&, const FloatRect& clipOutRect);
     void paintCompositionUnderlines();
     void paintPlatformDocumentMarkers();
 
-    static FloatRect calculateUnionOfAllDocumentMarkerBounds(const LegacyInlineTextBox&);
-
-private:
     enum class BackgroundStyle { Normal, Rounded };
     void paintBackground(unsigned startOffset, unsigned endOffset, const Color&, BackgroundStyle = BackgroundStyle::Normal);
+    void paintBackground(const StyledMarkedText&);
+    void paintForeground(const StyledMarkedText&);
+    void paintDecoration(const StyledMarkedText&, const FloatRect& clipOutRect);
     void paintCompositionUnderline(const CompositionUnderline&);
     void paintPlatformDocumentMarker(const MarkedText&);
-    
+
+    static FloatRect computePaintRect(const LegacyInlineTextBox&, const LayoutPoint& paintOffset);
     static FloatRect calculateDocumentMarkerBounds(const LegacyInlineTextBox&, const MarkedText&);
 
     const LegacyInlineTextBox& m_textBox;
+    const RenderText& m_renderer;
+    const Document& m_document;
     PaintInfo& m_paintInfo;
-    const FloatRect m_boxRect;
+    const FloatRect m_paintRect;
+    const bool m_isPrinting;
+    const bool m_haveSelection;
+    const bool m_containsComposition;
+    const bool m_useCustomUnderlines;
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to