Diff
Modified: trunk/Source/WebCore/ChangeLog (270146 => 270147)
--- trunk/Source/WebCore/ChangeLog 2020-11-21 15:15:20 UTC (rev 270146)
+++ trunk/Source/WebCore/ChangeLog 2020-11-21 16:33:23 UTC (rev 270147)
@@ -1,3 +1,24 @@
+2020-11-21 Antti Koivisto <[email protected]>
+
+ [LFC][Integration] Use inline iterator in collectSelectionRects
+ https://bugs.webkit.org/show_bug.cgi?id=219233
+
+ Reviewed by Zalan Bujtas.
+
+ Convert these iOS only functions.
+
+ * layout/integration/LayoutIntegrationLineIterator.h:
+ (WebCore::LayoutIntegration::PathLine::selectionHeight const):
+ * layout/integration/LayoutIntegrationRunIterator.h:
+ (WebCore::LayoutIntegration::PathRun::logicalTop const):
+ (WebCore::LayoutIntegration::PathRun::logicalBottom const):
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::collectSelectionRects):
+ * rendering/RenderLineBreak.cpp:
+ (WebCore::RenderLineBreak::collectSelectionRects):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::collectSelectionRects):
+
2020-11-21 Zalan Bujtas <[email protected]>
[LFC][Integration] LayoutIntegration::Line::rect is way too ambiguous
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIterator.h (270146 => 270147)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIterator.h 2020-11-21 15:15:20 UTC (rev 270146)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIterator.h 2020-11-21 16:33:23 UTC (rev 270147)
@@ -55,6 +55,7 @@
LayoutUnit selectionTop() const;
LayoutUnit selectionTopForHitTesting() const;
LayoutUnit selectionBottom() const;
+ LayoutUnit selectionHeight() const;
LayoutUnit lineBoxTop() const;
LayoutUnit lineBoxBottom() const;
@@ -164,6 +165,11 @@
});
}
+inline LayoutUnit PathLine::selectionHeight() const
+{
+ return selectionBottom() - selectionTop();
+}
+
inline LayoutUnit PathLine::lineBoxTop() const
{
return WTF::switchOn(m_pathVariant, [](const auto& path) {
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.h (270146 => 270147)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.h 2020-11-21 15:15:20 UTC (rev 270146)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.h 2020-11-21 16:33:23 UTC (rev 270147)
@@ -58,6 +58,8 @@
FloatRect rect() const;
+ float logicalTop() const { return isHorizontal() ? rect().y() : rect().x(); }
+ float logicalBottom() const { return isHorizontal() ? rect().maxY() : rect().maxX(); }
float logicalLeft() const { return isHorizontal() ? rect().x() : rect().y(); }
float logicalRight() const { return isHorizontal() ? rect().maxX() : rect().maxY(); }
float logicalWidth() const { return isHorizontal() ? rect().width() : rect().height(); }
Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (270146 => 270147)
--- trunk/Source/WebCore/rendering/RenderImage.cpp 2020-11-21 15:15:20 UTC (rev 270146)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp 2020-11-21 16:33:23 UTC (rev 270147)
@@ -45,6 +45,8 @@
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "InlineElementBox.h"
+#include "LayoutIntegrationLineIterator.h"
+#include "LayoutIntegrationRunIterator.h"
#include "Page.h"
#include "PaintInfo.h"
#include "RenderFragmentedFlow.h"
@@ -89,8 +91,8 @@
bool isFirstOnLine = false;
bool isLastOnLine = false;
- InlineBox* inlineBox = inlineBoxWrapper();
- if (!inlineBox) {
+ auto run = LayoutIntegration::runFor(*this);
+ if (!run) {
// This is a block image.
imageRect = IntRect(0, 0, width(), height());
isFirstOnLine = true;
@@ -104,15 +106,16 @@
lineExtentRect.setHeight(containingBlock->height());
}
} else {
- LayoutUnit selectionTop = !containingBlock->style().isFlippedBlocksWritingMode() ? inlineBox->root().selectionTop() - logicalTop() : logicalBottom() - inlineBox->root().selectionBottom();
- imageRect = IntRect(0, selectionTop, logicalWidth(), inlineBox->root().selectionHeight());
- isFirstOnLine = !inlineBox->previousOnLineExists();
- isLastOnLine = !inlineBox->nextOnLineExists();
+ auto line = run.line();
+ LayoutUnit selectionTop = !containingBlock->style().isFlippedBlocksWritingMode() ? line->selectionTop() - logicalTop() : logicalBottom() - line->selectionBottom();
+ imageRect = IntRect(0, selectionTop, logicalWidth(), line->selectionHeight());
+ isFirstOnLine = !run.previousOnLine();
+ isLastOnLine = !run.nextOnLine();
LogicalSelectionOffsetCaches cache(*containingBlock);
- LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, LayoutUnit(inlineBox->logicalTop()), cache);
- LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, LayoutUnit(inlineBox->logicalTop()), cache);
+ LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, LayoutUnit(run->logicalTop()), cache);
+ LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, LayoutUnit(run->logicalTop()), cache);
lineExtentRect = IntRect(leftOffset - logicalLeft(), imageRect.y(), rightOffset - leftOffset, imageRect.height());
- if (!inlineBox->isHorizontal()) {
+ if (!run->isHorizontal()) {
imageRect = imageRect.transposedRect();
lineExtentRect = lineExtentRect.transposedRect();
}
Modified: trunk/Source/WebCore/rendering/RenderLineBreak.cpp (270146 => 270147)
--- trunk/Source/WebCore/rendering/RenderLineBreak.cpp 2020-11-21 15:15:20 UTC (rev 270146)
+++ trunk/Source/WebCore/rendering/RenderLineBreak.cpp 2020-11-21 16:33:23 UTC (rev 270147)
@@ -34,6 +34,7 @@
#include "RenderBlock.h"
#include "RenderView.h"
#include "RootInlineBox.h"
+#include "SVGInlineTextBox.h"
#include "VisiblePosition.h"
#include <wtf/IsoMallocInlines.h>
@@ -207,29 +208,28 @@
#if PLATFORM(IOS_FAMILY)
void RenderLineBreak::collectSelectionRects(Vector<SelectionRect>& rects, unsigned, unsigned)
{
- ensureLineBoxes();
- InlineElementBox* box = m_inlineBoxWrapper;
- if (!box)
+ auto run = LayoutIntegration::runFor(*this);
+
+ if (!run)
return;
- const RootInlineBox& rootBox = box->root();
+ auto line = run.line();
- auto line = LayoutIntegration::LineIterator(&rootBox);
- LayoutRect rect = rootBox.blockFlow().computeCaretRect(line->selectionRect(), line->contentLogicalLeft(), 0);
+ LayoutRect rect = line->containingBlock().computeCaretRect(line->selectionRect(), line->contentLogicalLeft(), 0);
- if (rootBox.isFirstAfterPageBreak()) {
- if (box->isHorizontal())
- rect.shiftYEdgeTo(rootBox.lineBoxTop());
+ if (line->legacyRootInlineBox() && line->legacyRootInlineBox()->isFirstAfterPageBreak()) {
+ if (run->isHorizontal())
+ rect.shiftYEdgeTo(line->lineBoxTop());
else
- rect.shiftXEdgeTo(rootBox.lineBoxTop());
+ rect.shiftXEdgeTo(line->lineBoxTop());
}
auto* containingBlock = containingBlockForObjectInFlow();
// Map rect, extended left to leftOffset, and right to rightOffset, through transforms to get minX and maxX.
LogicalSelectionOffsetCaches cache(*containingBlock);
- LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, LayoutUnit(box->logicalTop()), cache);
- LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, LayoutUnit(box->logicalTop()), cache);
+ LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, LayoutUnit(run->logicalTop()), cache);
+ LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, LayoutUnit(run->logicalTop()), cache);
LayoutRect extentsRect = rect;
- if (box->isHorizontal()) {
+ if (run->isHorizontal()) {
extentsRect.setX(leftOffset);
extentsRect.setWidth(rightOffset - leftOffset);
} else {
@@ -237,16 +237,16 @@
extentsRect.setHeight(rightOffset - leftOffset);
}
extentsRect = localToAbsoluteQuad(FloatRect(extentsRect)).enclosingBoundingBox();
- if (!box->isHorizontal())
+ if (!run->isHorizontal())
extentsRect = extentsRect.transposedRect();
- bool isFirstOnLine = !box->previousOnLineExists();
- bool isLastOnLine = !box->nextOnLineExists();
+ bool isFirstOnLine = !run.previousOnLine();
+ bool isLastOnLine = !run.nextOnLine();
if (containingBlock->isRubyBase() || containingBlock->isRubyText())
isLastOnLine = !containingBlock->containingBlock()->inlineBoxWrapper()->nextOnLineExists();
bool isFixed = false;
IntRect absRect = localToAbsoluteQuad(FloatRect(rect), UseTransforms, &isFixed).enclosingBoundingBox();
- bool boxIsHorizontal = !box->isSVGInlineTextBox() ? box->isHorizontal() : !style().isVerticalWritingMode();
+ bool boxIsHorizontal = !is<SVGInlineTextBox>(run->legacyInlineBox()) ? run->isHorizontal() : !style().isVerticalWritingMode();
// If the containing block is an inline element, we want to check the inlineBoxWrapper orientation
// to determine the orientation of the block. In this case we also use the inlineBoxWrapper to
// determine if the element is the last on the line.
@@ -257,7 +257,7 @@
}
}
- rects.append(SelectionRect(absRect, box->direction(), extentsRect.x(), extentsRect.maxX(), extentsRect.maxY(), 0, box->isLineBreak(), isFirstOnLine, isLastOnLine, false, false, boxIsHorizontal, isFixed, containingBlock->isRubyText(), view().pageNumberForBlockProgressionOffset(absRect.x())));
+ rects.append(SelectionRect(absRect, run->direction(), extentsRect.x(), extentsRect.maxX(), extentsRect.maxY(), 0, run->isLineBreak(), isFirstOnLine, isLastOnLine, false, false, boxIsHorizontal, isFixed, containingBlock->isRubyText(), view().pageNumberForBlockProgressionOffset(absRect.x())));
}
#endif
Modified: trunk/Source/WebCore/rendering/RenderText.cpp (270146 => 270147)
--- trunk/Source/WebCore/rendering/RenderText.cpp 2020-11-21 15:15:20 UTC (rev 270146)
+++ trunk/Source/WebCore/rendering/RenderText.cpp 2020-11-21 16:33:23 UTC (rev 270147)
@@ -326,41 +326,31 @@
// Full annotations are added in this class.
void RenderText::collectSelectionRects(Vector<SelectionRect>& rects, unsigned start, unsigned end)
{
- // FIXME: Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
- // to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
- // function to take ints causes various internal mismatches. But selectionRect takes ints, and
- // passing UINT_MAX to it causes trouble. Ideally we'd change selectionRect to take unsigneds, but
- // that would cause many ripple effects, so for now we'll just clamp our unsigned parameters to INT_MAX.
- ASSERT(end == std::numeric_limits<unsigned>::max() || end <= std::numeric_limits<int>::max());
- ASSERT(start <= std::numeric_limits<int>::max());
- start = std::min(start, static_cast<unsigned>(std::numeric_limits<int>::max()));
- end = std::min(end, static_cast<unsigned>(std::numeric_limits<int>::max()));
-
- for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
+ for (auto run = LayoutIntegration::firstTextRunFor(*this); run; run = run.traverseNextTextRun()) {
LayoutRect rect;
- if (start <= box->start() && box->end() <= end)
- rect = box->localSelectionRect(start, end);
+ if (start <= run->start() && run->end() <= end)
+ rect = run->selectionRect(start, end);
else {
- unsigned realEnd = std::min(box->end(), end);
- rect = box->localSelectionRect(start, realEnd);
+ unsigned realEnd = std::min(run->end(), end);
+ rect = run->selectionRect(start, realEnd);
if (rect.isEmpty())
continue;
}
- if (box->root().isFirstAfterPageBreak()) {
- if (box->isHorizontal())
- rect.shiftYEdgeTo(box->root().lineBoxTop());
+ if (run.line()->legacyRootInlineBox() && run.line()->legacyRootInlineBox()->isFirstAfterPageBreak()) {
+ if (run->isHorizontal())
+ rect.shiftYEdgeTo(run.line()->lineBoxTop());
else
- rect.shiftXEdgeTo(box->root().lineBoxTop());
+ rect.shiftXEdgeTo(run.line()->lineBoxTop());
}
RenderBlock* containingBlock = this->containingBlock();
// Map rect, extended left to leftOffset, and right to rightOffset, through transforms to get minX and maxX.
LogicalSelectionOffsetCaches cache(*containingBlock);
- LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, LayoutUnit(box->logicalTop()), cache);
- LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, LayoutUnit(box->logicalTop()), cache);
+ LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, LayoutUnit(run->logicalTop()), cache);
+ LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, LayoutUnit(run->logicalTop()), cache);
LayoutRect extentsRect = rect;
- if (box->isHorizontal()) {
+ if (run->isHorizontal()) {
extentsRect.setX(leftOffset);
extentsRect.setWidth(rightOffset - leftOffset);
} else {
@@ -368,19 +358,19 @@
extentsRect.setHeight(rightOffset - leftOffset);
}
extentsRect = localToAbsoluteQuad(FloatRect(extentsRect)).enclosingBoundingBox();
- if (!box->isHorizontal())
+ if (!run->isHorizontal())
extentsRect = extentsRect.transposedRect();
- bool isFirstOnLine = !box->previousOnLineExists();
- bool isLastOnLine = !box->nextOnLineExists();
+ bool isFirstOnLine = !run.previousOnLine();
+ bool isLastOnLine = !run.nextOnLine();
if (containingBlock->isRubyBase() || containingBlock->isRubyText())
isLastOnLine = !containingBlock->containingBlock()->inlineBoxWrapper()->nextOnLineExists();
- bool containsStart = box->start() <= start && box->end() >= start;
- bool containsEnd = box->start() <= end && box->end() >= end;
+ bool containsStart = run->start() <= start && run->end() >= start;
+ bool containsEnd = run->start() <= end && run->end() >= end;
bool isFixed = false;
IntRect absRect = localToAbsoluteQuad(FloatRect(rect), UseTransforms, &isFixed).enclosingBoundingBox();
- bool boxIsHorizontal = !box->isSVGInlineTextBox() ? box->isHorizontal() : !style().isVerticalWritingMode();
+ bool boxIsHorizontal = !is<SVGInlineTextBox>(run->legacyInlineBox()) ? run->isHorizontal() : !style().isVerticalWritingMode();
// If the containing block is an inline element, we want to check the inlineBoxWrapper orientation
// to determine the orientation of the block. In this case we also use the inlineBoxWrapper to
// determine if the element is the last on the line.
@@ -391,7 +381,7 @@
}
}
- rects.append(SelectionRect(absRect, box->direction(), extentsRect.x(), extentsRect.maxX(), extentsRect.maxY(), 0, box->isLineBreak(), isFirstOnLine, isLastOnLine, containsStart, containsEnd, boxIsHorizontal, isFixed, containingBlock->isRubyText(), view().pageNumberForBlockProgressionOffset(absRect.x())));
+ rects.append(SelectionRect(absRect, run->direction(), extentsRect.x(), extentsRect.maxX(), extentsRect.maxY(), 0, run->isLineBreak(), isFirstOnLine, isLastOnLine, containsStart, containsEnd, boxIsHorizontal, isFixed, containingBlock->isRubyText(), view().pageNumberForBlockProgressionOffset(absRect.x())));
}
}
#endif