Title: [269301] trunk/Source/WebCore
Revision
269301
Author
[email protected]
Date
2020-11-03 06:34:01 -0800 (Tue, 03 Nov 2020)

Log Message

[LFC][Integration] RenderText::absoluteQuads should use iterator
https://bugs.webkit.org/show_bug.cgi?id=218508

Reviewed by Zalan Bujtas.

* rendering/InlineBox.h:
(WebCore::InlineBox::calculateBoundaries const): Deleted.

This function is SVG-specific.
To reduce confusion, make it non-virtual and available in SVG inline box classes only.

* rendering/InlineTextBox.h:
* rendering/RenderText.cpp:
(WebCore::boundariesForTextRun):
(WebCore::ellipsisRectForTextRun):
(WebCore::collectAbsoluteQuads):
(WebCore::RenderText::absoluteQuadsClippedToEllipsis const):
(WebCore::RenderText::absoluteQuads const):
(WebCore::RenderText::absoluteQuadsForRange const):
(WebCore::RenderText::collectSelectionRectsForLineBoxes):

Also inline selectionRectForRange/collectSelectionRectsForRange to the only caller here and make it use iterator.

(WebCore::collectAbsoluteQuadsForNonComplexPaths): Deleted.
* rendering/RenderTextLineBoxes.cpp:
(WebCore::ellipsisRectForBox): Deleted.
(WebCore::RenderTextLineBoxes::selectionRectForRange): Deleted.
(WebCore::RenderTextLineBoxes::collectSelectionRectsForRange): Deleted.
(WebCore::RenderTextLineBoxes::absoluteQuads const): Deleted.
* rendering/RenderTextLineBoxes.h:
(): Deleted.
* rendering/svg/RenderSVGInlineText.cpp:
(WebCore::RenderSVGInlineText::floatLinesBoundingBox const):
(WebCore::RenderSVGInlineText::positionForPoint):
(WebCore::RenderSVGInlineText::firstTextBox const):
* rendering/svg/RenderSVGInlineText.h:
* rendering/svg/SVGInlineFlowBox.cpp:
(WebCore::SVGInlineFlowBox::calculateBoundaries const):
* rendering/svg/SVGInlineFlowBox.h:
* rendering/svg/SVGInlineTextBox.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (269300 => 269301)


--- trunk/Source/WebCore/ChangeLog	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/ChangeLog	2020-11-03 14:34:01 UTC (rev 269301)
@@ -1,3 +1,46 @@
+2020-11-03  Antti Koivisto  <[email protected]>
+
+        [LFC][Integration] RenderText::absoluteQuads should use iterator
+        https://bugs.webkit.org/show_bug.cgi?id=218508
+
+        Reviewed by Zalan Bujtas.
+
+        * rendering/InlineBox.h:
+        (WebCore::InlineBox::calculateBoundaries const): Deleted.
+
+        This function is SVG-specific.
+        To reduce confusion, make it non-virtual and available in SVG inline box classes only.
+
+        * rendering/InlineTextBox.h:
+        * rendering/RenderText.cpp:
+        (WebCore::boundariesForTextRun):
+        (WebCore::ellipsisRectForTextRun):
+        (WebCore::collectAbsoluteQuads):
+        (WebCore::RenderText::absoluteQuadsClippedToEllipsis const):
+        (WebCore::RenderText::absoluteQuads const):
+        (WebCore::RenderText::absoluteQuadsForRange const):
+        (WebCore::RenderText::collectSelectionRectsForLineBoxes):
+
+        Also inline selectionRectForRange/collectSelectionRectsForRange to the only caller here and make it use iterator.
+
+        (WebCore::collectAbsoluteQuadsForNonComplexPaths): Deleted.
+        * rendering/RenderTextLineBoxes.cpp:
+        (WebCore::ellipsisRectForBox): Deleted.
+        (WebCore::RenderTextLineBoxes::selectionRectForRange): Deleted.
+        (WebCore::RenderTextLineBoxes::collectSelectionRectsForRange): Deleted.
+        (WebCore::RenderTextLineBoxes::absoluteQuads const): Deleted.
+        * rendering/RenderTextLineBoxes.h:
+        (): Deleted.
+        * rendering/svg/RenderSVGInlineText.cpp:
+        (WebCore::RenderSVGInlineText::floatLinesBoundingBox const):
+        (WebCore::RenderSVGInlineText::positionForPoint):
+        (WebCore::RenderSVGInlineText::firstTextBox const):
+        * rendering/svg/RenderSVGInlineText.h:
+        * rendering/svg/SVGInlineFlowBox.cpp:
+        (WebCore::SVGInlineFlowBox::calculateBoundaries const):
+        * rendering/svg/SVGInlineFlowBox.h:
+        * rendering/svg/SVGInlineTextBox.h:
+
 2020-11-03  Zalan Bujtas  <[email protected]>
 
         [LFC][IFC] Use "isConsideredEmpty" instead of "isVisuallyEmpty"

Modified: trunk/Source/WebCore/rendering/InlineBox.h (269300 => 269301)


--- trunk/Source/WebCore/rendering/InlineBox.h	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/InlineBox.h	2020-11-03 14:34:01 UTC (rev 269301)
@@ -104,12 +104,6 @@
     bool isHorizontal() const { return m_bitfields.isHorizontal(); }
     void setIsHorizontal(bool isHorizontal) { m_bitfields.setIsHorizontal(isHorizontal); }
 
-    virtual FloatRect calculateBoundaries() const
-    {
-        ASSERT_NOT_REACHED();
-        return FloatRect();
-    }
-
     bool isConstructed() { return m_bitfields.constructed(); }
     virtual void setConstructed() { m_bitfields.setConstructed(true); }
 

Modified: trunk/Source/WebCore/rendering/InlineTextBox.h (269300 => 269301)


--- trunk/Source/WebCore/rendering/InlineTextBox.h	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/InlineTextBox.h	2020-11-03 14:34:01 UTC (rev 269301)
@@ -116,8 +116,6 @@
     LayoutUnit selectionHeight() const;
 
 public:
-    FloatRect calculateBoundaries() const override { return FloatRect(x(), y(), width(), height()); }
-
     virtual LayoutRect localSelectionRect(unsigned startPos, unsigned endPos) const;
     bool isSelected(unsigned startPosition, unsigned endPosition) const;
     std::pair<unsigned, unsigned> selectionStartEnd() const;

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (269300 => 269301)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2020-11-03 14:34:01 UTC (rev 269301)
@@ -47,6 +47,7 @@
 #include "RenderLayer.h"
 #include "RenderView.h"
 #include "RenderedDocumentMarker.h"
+#include "SVGInlineTextBox.h"
 #include "Settings.h"
 #include "Text.h"
 #include "TextResourceDecoder.h"
@@ -394,33 +395,75 @@
 }
 #endif
 
-static Vector<FloatQuad> collectAbsoluteQuadsForNonComplexPaths(const RenderText& textRenderer, bool* wasFixed)
+static FloatRect boundariesForTextRun(const LayoutIntegration::PathTextRun& run)
 {
-    // FIXME: This generic function doesn't currently cover everything that is needed for the complex line layout path.
-    ASSERT(!textRenderer.usesComplexLineLayoutPath());
+    if (is<SVGInlineTextBox>(run.legacyInlineBox()))
+        return downcast<SVGInlineTextBox>(*run.legacyInlineBox()).calculateBoundaries();
 
+    return run.rect();
+}
+
+static IntRect ellipsisRectForTextRun(const LayoutIntegration::PathTextRun& run, unsigned start, unsigned end)
+{
+    // FIXME: No ellipsis support in modern path yet.
+    if (!run.legacyInlineBox())
+        return { };
+
+    auto& box = *run.legacyInlineBox();
+
+    unsigned short truncation = box.truncation();
+    if (truncation == cNoTruncation)
+        return { };
+
+    auto ellipsis = box.root().ellipsisBox();
+    if (!ellipsis)
+        return { };
+
+    int ellipsisStartPosition = std::max<int>(start - box.start(), 0);
+    int ellipsisEndPosition = std::min<int>(end - box.start(), box.len());
+
+    // The ellipsis should be considered to be selected if the end of
+    // the selection is past the beginning of the truncation and the
+    // beginning of the selection is before or at the beginning of the truncation.
+    if (ellipsisEndPosition < truncation && ellipsisStartPosition > truncation)
+        return { };
+
+    return ellipsis->selectionRect();
+}
+
+enum class ClippingOption { NoClipping, ClipToEllipsis };
+
+// FIXME: Unify with absoluteQuadsForRange.
+static Vector<FloatQuad> collectAbsoluteQuads(const RenderText& textRenderer, bool* wasFixed, ClippingOption clipping)
+{
     Vector<FloatQuad> quads;
-    for (auto& run : LayoutIntegration::textRunsFor(textRenderer))
-        quads.append(textRenderer.localToAbsoluteQuad(FloatQuad(run.rect()), UseTransforms, wasFixed));
+    for (auto& run : LayoutIntegration::textRunsFor(textRenderer)) {
+        auto boundaries = boundariesForTextRun(run);
+
+        // Shorten the width of this text box if it ends in an ellipsis.
+        if (clipping == ClippingOption::ClipToEllipsis) {
+            auto ellipsisRect = ellipsisRectForTextRun(run, 0, textRenderer.text().length());
+            if (!ellipsisRect.isEmpty()) {
+                if (textRenderer.style().isHorizontalWritingMode())
+                    boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
+                else
+                    boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
+            }
+        }
+        
+        quads.append(textRenderer.localToAbsoluteQuad(boundaries, UseTransforms, wasFixed));
+    }
     return quads;
 }
 
 Vector<FloatQuad> RenderText::absoluteQuadsClippedToEllipsis() const
 {
-    if (!usesComplexLineLayoutPath()) {
-        ASSERT(style().textOverflow() != TextOverflow::Ellipsis);
-        return collectAbsoluteQuadsForNonComplexPaths(*this, nullptr);
-    }
-    return m_lineBoxes.absoluteQuads(*this, nullptr, RenderTextLineBoxes::ClipToEllipsis);
+    return collectAbsoluteQuads(*this, nullptr, ClippingOption::ClipToEllipsis);
 }
 
 void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
 {
-    if (!usesComplexLineLayoutPath()) {
-        quads.appendVector(collectAbsoluteQuadsForNonComplexPaths(*this, wasFixed));
-        return;
-    }
-    quads.appendVector(m_lineBoxes.absoluteQuads(*this, wasFixed, RenderTextLineBoxes::NoClipping));
+    quads.appendVector(collectAbsoluteQuads(*this, wasFixed, ClippingOption::NoClipping));
 }
 
 static FloatRect localQuadForTextRun(const LayoutIntegration::PathTextRun& run, unsigned start, unsigned end, bool useSelectionHeight)
@@ -460,11 +503,7 @@
         if (ignoreEmptyTextSelections && !run.isSelectable(start, end))
             continue;
         if (start <= run.start() && run.end() <= end) {
-            auto boundaries = [&] {
-                if (run.legacyInlineBox() && run.legacyInlineBox()->isSVGInlineTextBox())
-                    return run.legacyInlineBox()->calculateBoundaries();
-                return run.rect();
-            }();
+            auto boundaries = boundariesForTextRun(run);
 
             if (useSelectionHeight) {
                 LayoutRect selectionRect = run.selectionRect(start, end);
@@ -1621,14 +1660,18 @@
         return IntRect();
 
     LayoutRect resultRect;
-    if (!rects)
-        resultRect = m_lineBoxes.selectionRectForRange(startOffset, endOffset);
-    else {
-        m_lineBoxes.collectSelectionRectsForRange(startOffset, endOffset, *rects);
-        for (auto& rect : *rects) {
-            resultRect.unite(rect);
-            rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
-        }
+
+    for (auto& run : LayoutIntegration::textRunsFor(*this)) {
+        LayoutRect rect;
+        rect.unite(run.selectionRect(startOffset, endOffset));
+        rect.unite(ellipsisRectForTextRun(run, startOffset, endOffset));
+        if (rect.isEmpty())
+            continue;
+
+        resultRect.unite(rect);
+
+        if (rects)
+            rects->append(localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox());
     }
 
     if (clipToVisibleContent)

Modified: trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp (269300 => 269301)


--- trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp	2020-11-03 14:34:01 UTC (rev 269301)
@@ -194,69 +194,6 @@
     }
 }
 
-static IntRect ellipsisRectForBox(const InlineTextBox& box, unsigned start, unsigned end)
-{
-    unsigned short truncation = box.truncation();
-    if (truncation == cNoTruncation)
-        return IntRect();
-
-    auto ellipsis = box.root().ellipsisBox();
-    if (!ellipsis)
-        return IntRect();
-    
-    IntRect rect;
-    int ellipsisStartPosition = std::max<int>(start - box.start(), 0);
-    int ellipsisEndPosition = std::min<int>(end - box.start(), box.len());
-    
-    // The ellipsis should be considered to be selected if the end of
-    // the selection is past the beginning of the truncation and the
-    // beginning of the selection is before or at the beginning of the truncation.
-    if (ellipsisEndPosition < truncation && ellipsisStartPosition > truncation)
-        return IntRect();
-    return ellipsis->selectionRect();
-}
-
-LayoutRect RenderTextLineBoxes::selectionRectForRange(unsigned start, unsigned end)
-{
-    LayoutRect rect;
-    for (auto* box = m_first; box; box = box->nextTextBox()) {
-        rect.unite(box->localSelectionRect(start, end));
-        rect.unite(ellipsisRectForBox(*box, start, end));
-    }
-    return rect;
-}
-
-void RenderTextLineBoxes::collectSelectionRectsForRange(unsigned start, unsigned end, Vector<LayoutRect>& rects)
-{
-    for (auto* box = m_first; box; box = box->nextTextBox()) {
-        LayoutRect rect;
-        rect.unite(box->localSelectionRect(start, end));
-        rect.unite(ellipsisRectForBox(*box, start, end));
-        if (!rect.size().isEmpty())
-            rects.append(rect);
-    }
-}
-
-Vector<FloatQuad> RenderTextLineBoxes::absoluteQuads(const RenderText& renderer, bool* wasFixed, ClippingOption option) const
-{
-    Vector<FloatQuad> quads;
-    for (auto* box = m_first; box; box = box->nextTextBox()) {
-        FloatRect boundaries = box->calculateBoundaries();
-
-        // Shorten the width of this text box if it ends in an ellipsis.
-        // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch.
-        IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(*box, 0, renderer.text().length()) : IntRect();
-        if (!ellipsisRect.isEmpty()) {
-            if (renderer.style().isHorizontalWritingMode())
-                boundaries.setWidth(ellipsisRect.maxX() - boundaries.x());
-            else
-                boundaries.setHeight(ellipsisRect.maxY() - boundaries.y());
-        }
-        quads.append(renderer.localToAbsoluteQuad(boundaries, UseTransforms, wasFixed));
-    }
-    return quads;
-}
-
 void RenderTextLineBoxes::dirtyAll()
 {
     for (auto* box = m_first; box; box = box->nextTextBox())

Modified: trunk/Source/WebCore/rendering/RenderTextLineBoxes.h (269300 => 269301)


--- trunk/Source/WebCore/rendering/RenderTextLineBoxes.h	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/RenderTextLineBoxes.h	2020-11-03 14:34:01 UTC (rev 269301)
@@ -57,14 +57,9 @@
     InlineTextBox* findNext(int offset, int& position) const;
 
     void setSelectionState(RenderText&, RenderObject::HighlightState);
-    LayoutRect selectionRectForRange(unsigned start, unsigned end);
-    void collectSelectionRectsForRange(unsigned start, unsigned end, Vector<LayoutRect>& rects);
 
     LayoutRect visualOverflowBoundingBox(const RenderText&) const;
 
-    enum ClippingOption { NoClipping, ClipToEllipsis };
-    Vector<FloatQuad> absoluteQuads(const RenderText&, bool* wasFixed, ClippingOption) const;
-
 #if ASSERT_ENABLED
     ~RenderTextLineBoxes();
 #endif

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp (269300 => 269301)


--- trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp	2020-11-03 14:34:01 UTC (rev 269301)
@@ -142,8 +142,9 @@
 FloatRect RenderSVGInlineText::floatLinesBoundingBox() const
 {
     FloatRect boundingBox;
-    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
+    for (auto* box = firstTextBox(); box; box = box->nextTextBox())
         boundingBox.unite(box->calculateBoundaries());
+
     return boundingBox;
 }
 
@@ -188,13 +189,9 @@
     SVGInlineTextBox* closestDistanceBox = nullptr;
 
     AffineTransform fragmentTransform;
-    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
-        if (!is<SVGInlineTextBox>(*box))
-            continue;
+    for (auto* box = firstTextBox(); box; box = box->nextTextBox()) {
+        Vector<SVGTextFragment>& fragments = box->textFragments();
 
-        auto& textBox = downcast<SVGInlineTextBox>(*box);
-        Vector<SVGTextFragment>& fragments = textBox.textFragments();
-
         unsigned textFragmentsSize = fragments.size();
         for (unsigned i = 0; i < textFragmentsSize; ++i) {
             const SVGTextFragment& fragment = fragments.at(i);
@@ -208,7 +205,7 @@
 
             if (distance < closestDistance) {
                 closestDistance = distance;
-                closestDistanceBox = &textBox;
+                closestDistanceBox = box;
                 closestDistanceFragment = &fragment;
                 closestDistancePosition = fragmentRect.x();
             }
@@ -251,4 +248,9 @@
     scaledFont.update(&renderer.document().fontSelector());
 }
 
+SVGInlineTextBox* RenderSVGInlineText::firstTextBox() const
+{
+    return downcast<SVGInlineTextBox>(RenderText::firstTextBox());
 }
+
+}

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.h (269300 => 269301)


--- trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.h	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGInlineText.h	2020-11-03 14:34:01 UTC (rev 269301)
@@ -48,6 +48,8 @@
     // Preserves floating point precision for the use in DRT. It knows how to round and does a better job than enclosingIntRect.
     FloatRect floatLinesBoundingBox() const;
 
+    SVGInlineTextBox* firstTextBox() const;
+
 private:
     const char* renderName() const override { return "RenderSVGInlineText"; }
 

Modified: trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp (269300 => 269301)


--- trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp	2020-11-03 14:34:01 UTC (rev 269301)
@@ -62,10 +62,15 @@
 FloatRect SVGInlineFlowBox::calculateBoundaries() const
 {
     FloatRect childRect;
-    for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
-        if (!child->isSVGInlineTextBox() && !child->isSVGInlineFlowBox())
+    for (auto* child = firstChild(); child; child = child->nextOnLine()) {
+        if (is<SVGInlineTextBox>(child)) {
+            childRect.unite(downcast<SVGInlineTextBox>(*child).calculateBoundaries());
             continue;
-        childRect.unite(child->calculateBoundaries());
+        }
+        if (is<SVGInlineFlowBox>(child)) {
+            childRect.unite(downcast<SVGInlineFlowBox>(*child).calculateBoundaries());
+            continue;
+        }
     }
     return childRect;
 }

Modified: trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.h (269300 => 269301)


--- trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.h	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/svg/SVGInlineFlowBox.h	2020-11-03 14:34:01 UTC (rev 269301)
@@ -38,7 +38,7 @@
 
     RenderSVGInline& renderer() { return static_cast<RenderSVGInline&>(InlineFlowBox::renderer()); }
 
-    FloatRect calculateBoundaries() const override;
+    FloatRect calculateBoundaries() const;
 
     void setLogicalHeight(float h) { m_logicalHeight = h; }
     void paintSelectionBackground(PaintInfo&);

Modified: trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.h (269300 => 269301)


--- trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.h	2020-11-03 14:20:47 UTC (rev 269300)
+++ trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.h	2020-11-03 14:34:01 UTC (rev 269301)
@@ -24,12 +24,12 @@
 #include "InlineTextBox.h"
 #include "RenderSVGInlineText.h"
 #include "RenderSVGResource.h"
+#include "SVGTextFragment.h"
 
 namespace WebCore {
 
 class RenderSVGResource;
 class SVGRootInlineBox;
-struct SVGTextFragment;
 
 class SVGInlineTextBox final : public InlineTextBox {
     WTF_MAKE_ISO_ALLOCATED(SVGInlineTextBox);
@@ -52,7 +52,7 @@
 
     bool mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment&, unsigned& startPosition, unsigned& endPosition) const;
 
-    FloatRect calculateBoundaries() const override;
+    FloatRect calculateBoundaries() const;
 
     void clearTextFragments() { m_textFragments.clear(); }
     Vector<SVGTextFragment>& textFragments() { return m_textFragments; }
@@ -69,6 +69,8 @@
     
     OptionSet<RenderSVGResourceMode> paintingResourceMode() const { return OptionSet<RenderSVGResourceMode>::fromRaw(m_paintingResourceMode); }
     void setPaintingResourceMode(OptionSet<RenderSVGResourceMode> mode) { m_paintingResourceMode = mode.toRaw(); }
+
+    SVGInlineTextBox* nextTextBox() const { return downcast<SVGInlineTextBox>(InlineTextBox::nextTextBox()); }
     
 private:
     bool isSVGInlineTextBox() const override { return true; }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to