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