Diff
Modified: trunk/Source/WebCore/ChangeLog (250518 => 250519)
--- trunk/Source/WebCore/ChangeLog 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/ChangeLog 2019-09-30 15:55:37 UTC (rev 250519)
@@ -1,3 +1,77 @@
+2019-09-30 Antti Koivisto <[email protected]>
+
+ RenderLineBreak should use LineLayoutTraversal
+ https://bugs.webkit.org/show_bug.cgi?id=202316
+
+ Reviewed by Zalan Bujtas.
+
+ Replace more path specific code with LineLayoutTraversal.
+
+ * Headers.cmake:
+ * rendering/RenderLineBreak.cpp:
+ (WebCore::RenderLineBreak::linesBoundingBox const):
+ (WebCore::RenderLineBreak::absoluteRects const):
+ (WebCore::RenderLineBreak::absoluteQuads const):
+ (WebCore::simpleLineLayout): Deleted.
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::RenderTreeAsText::writeRenderObject):
+ (WebCore::writeTextBox):
+ * rendering/SimpleLineLayoutFunctions.cpp:
+ (WebCore::SimpleLineLayout::computeBoundingBox): Deleted.
+ (WebCore::SimpleLineLayout::collectAbsoluteRects): Deleted.
+ (WebCore::SimpleLineLayout::rendererForPosition): Deleted.
+ * rendering/SimpleLineLayoutFunctions.h:
+ * rendering/line/LineLayoutTraversal.cpp:
+ (WebCore::LineLayoutTraversal::ElementBoxIterator::ElementBoxIterator):
+ (WebCore::LineLayoutTraversal::ElementBoxIterator::atEnd const):
+ (WebCore::LineLayoutTraversal::elementBoxFor):
+ (WebCore::LineLayoutTraversal::TextBox::rect const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::logicalRect const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::hasHyphen const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::isLeftToRightDirection const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::dirOverride const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::text const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::isLineBreak const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::localStartOffset const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::localEndOffset const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::length const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::isLastOnLine const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::isLast const): Deleted.
+ (WebCore::LineLayoutTraversal::TextBox::iterator const): Deleted.
+
+ Move to header as templates.
+
+ * rendering/line/LineLayoutTraversal.h:
+ (WebCore::LineLayoutTraversal::ElementBoxIterator::ElementBoxIterator):
+ (WebCore::LineLayoutTraversal::ElementBoxIterator::operator bool const):
+ (WebCore::LineLayoutTraversal::ElementBoxIterator::operator* const):
+ (WebCore::LineLayoutTraversal::ElementBoxIterator::operator-> const):
+
+ Add a new iterator type for element boxes.
+ It doesn't currently really iterate, is just allows testing for end.
+
+ (WebCore::LineLayoutTraversal::Box<Iterator>::rect const):
+ (WebCore::LineLayoutTraversal::Box<Iterator>::logicalRect const):
+ (WebCore::LineLayoutTraversal::Box<Iterator>::isLeftToRightDirection const):
+ (WebCore::LineLayoutTraversal::Box<Iterator>::dirOverride const):
+ (WebCore::LineLayoutTraversal::Box<Iterator>::isLineBreak const):
+ (WebCore::LineLayoutTraversal::Box<Iterator>::iterator const):
+
+ Split properties that all inline boxes have out from TextBox.
+ Make it a template class.
+
+ (WebCore::LineLayoutTraversal::TextBox<Iterator>::hasHyphen const):
+ (WebCore::LineLayoutTraversal::TextBox<Iterator>::text const):
+ (WebCore::LineLayoutTraversal::TextBox<Iterator>::localStartOffset const):
+ (WebCore::LineLayoutTraversal::TextBox<Iterator>::localEndOffset const):
+ (WebCore::LineLayoutTraversal::TextBox<Iterator>::length const):
+ (WebCore::LineLayoutTraversal::TextBox<Iterator>::isLastOnLine const):
+ (WebCore::LineLayoutTraversal::TextBox<Iterator>::isLast const):
+
+ Make a template class.
+
+ (WebCore::LineLayoutTraversal::hasTextBoxes): Deleted.
+
2019-09-30 Rob Buis <[email protected]>
No-Cors check should take into account same-origin
Modified: trunk/Source/WebCore/Headers.cmake (250518 => 250519)
--- trunk/Source/WebCore/Headers.cmake 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/Headers.cmake 2019-09-30 15:55:37 UTC (rev 250519)
@@ -1251,7 +1251,9 @@
rendering/HitTestRequest.h
rendering/HitTestResult.h
rendering/InlineBox.h
+ rendering/InlineElementBox.h
rendering/InlineFlowBox.h
+ rendering/InlineTextBox.h
rendering/LayerAncestorClippingStack.h
rendering/LayerFragment.h
rendering/MarkedText.h
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (250518 => 250519)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-09-30 15:55:37 UTC (rev 250519)
@@ -3657,7 +3657,7 @@
B562DB6017D3CD630010AF96 /* HTMLElementTypeHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = B562DB5E17D3CD560010AF96 /* HTMLElementTypeHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
B562DB6117D3CD660010AF96 /* SVGElementTypeHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = B562DB5F17D3CD560010AF96 /* SVGElementTypeHelpers.h */; };
B56579B51824D12A00E79F23 /* RenderChildIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = B56579B41824D12A00E79F23 /* RenderChildIterator.h */; };
- B57CB52E182A3EFC0079A647 /* InlineElementBox.h in Headers */ = {isa = PBXBuildFile; fileRef = B57CB52B182A37F60079A647 /* InlineElementBox.h */; };
+ B57CB52E182A3EFC0079A647 /* InlineElementBox.h in Headers */ = {isa = PBXBuildFile; fileRef = B57CB52B182A37F60079A647 /* InlineElementBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
B595FF471824CEE300FF51CD /* RenderIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = B595FF461824CEE300FF51CD /* RenderIterator.h */; };
B59DD699119029E5007E9684 /* JSDatabaseCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B59DD697119029E5007E9684 /* JSDatabaseCallback.h */; };
B59DD69D11902A42007E9684 /* JSSQLTransactionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B59DD69B11902A42007E9684 /* JSSQLTransactionCallback.h */; };
Modified: trunk/Source/WebCore/rendering/RenderLineBreak.cpp (250518 => 250519)
--- trunk/Source/WebCore/rendering/RenderLineBreak.cpp 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/rendering/RenderLineBreak.cpp 2019-09-30 15:55:37 UTC (rev 250519)
@@ -27,11 +27,11 @@
#include "HTMLElement.h"
#include "HTMLWBRElement.h"
#include "InlineElementBox.h"
+#include "LineLayoutTraversal.h"
#include "LogicalSelectionOffsetCaches.h"
#include "RenderBlock.h"
#include "RenderView.h"
#include "RootInlineBox.h"
-#include "SimpleLineLayoutFunctions.h"
#include "VisiblePosition.h"
#include <wtf/IsoMallocInlines.h>
@@ -45,13 +45,6 @@
static const int invalidLineHeight = -1;
-static const SimpleLineLayout::Layout* simpleLineLayout(const RenderLineBreak& renderer)
-{
- if (!is<RenderBlockFlow>(*renderer.parent()))
- return nullptr;
- return downcast<RenderBlockFlow>(*renderer.parent()).simpleLineLayout();
-}
-
RenderLineBreak::RenderLineBreak(HTMLElement& element, RenderStyle&& style)
: RenderBoxModelObject(element, WTFMove(style), 0)
, m_inlineBoxWrapper(nullptr)
@@ -183,45 +176,31 @@
IntRect RenderLineBreak::linesBoundingBox() const
{
- if (auto* layout = simpleLineLayout(*this))
- return SimpleLineLayout::computeBoundingBox(*this, *layout);
+ auto box = LineLayoutTraversal::elementBoxFor(*this);
+ if (!box)
+ return { };
- if (!m_inlineBoxWrapper)
- return IntRect();
-
- float logicalLeftSide = m_inlineBoxWrapper->logicalLeft();
- float logicalRightSide = m_inlineBoxWrapper->logicalRight();
-
- bool isHorizontal = style().isHorizontalWritingMode();
-
- float x = isHorizontal ? logicalLeftSide : m_inlineBoxWrapper->x();
- float y = isHorizontal ? m_inlineBoxWrapper->y() : logicalLeftSide;
- float width = isHorizontal ? logicalRightSide - logicalLeftSide : m_inlineBoxWrapper->logicalBottom() - x;
- float height = isHorizontal ? m_inlineBoxWrapper->logicalBottom() - y : logicalRightSide - logicalLeftSide;
- return enclosingIntRect(FloatRect(x, y, width, height));
+ return enclosingIntRect(box->rect());
}
void RenderLineBreak::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
{
- if (auto* layout = simpleLineLayout(*this)) {
- rects.appendVector(SimpleLineLayout::collectAbsoluteRects(*this, *layout, accumulatedOffset));
+ auto box = LineLayoutTraversal::elementBoxFor(*this);
+ if (!box)
return;
- }
- if (!m_inlineBoxWrapper)
- return;
- rects.append(enclosingIntRect(FloatRect(accumulatedOffset + m_inlineBoxWrapper->topLeft(), m_inlineBoxWrapper->size())));
+ auto rect = box->rect();
+ rects.append(enclosingIntRect(FloatRect(accumulatedOffset + rect.location(), rect.size())));
}
void RenderLineBreak::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
{
- if (auto* layout = simpleLineLayout(*this)) {
- quads.appendVector(SimpleLineLayout::collectAbsoluteQuads(*this, *layout, wasFixed));
+ auto box = LineLayoutTraversal::elementBoxFor(*this);
+ if (!box)
return;
- }
- if (!m_inlineBoxWrapper)
- return;
- quads.append(localToAbsoluteQuad(FloatRect(m_inlineBoxWrapper->topLeft(), m_inlineBoxWrapper->size()), UseTransforms, wasFixed));
+
+ auto rect = box->rect();
+ quads.append(localToAbsoluteQuad(FloatRect(rect.location(), rect.size()), UseTransforms, wasFixed));
}
void RenderLineBreak::updateFromStyle()
Modified: trunk/Source/WebCore/rendering/RenderTreeAsText.cpp (250518 => 250519)
--- trunk/Source/WebCore/rendering/RenderTreeAsText.cpp 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/rendering/RenderTreeAsText.cpp 2019-09-30 15:55:37 UTC (rev 250519)
@@ -202,7 +202,7 @@
// many test results.
const RenderText& text = downcast<RenderText>(o);
r = IntRect(text.firstRunLocation(), text.linesBoundingBox().size());
- if (!LineLayoutTraversal::hasTextBoxes(text))
+ if (!LineLayoutTraversal::firstTextBoxFor(text))
adjustForTableCells = false;
} else if (o.isBR()) {
const RenderLineBreak& br = downcast<RenderLineBreak>(o);
@@ -477,7 +477,7 @@
}
}
-static void writeTextBox(TextStream& ts, const RenderText& o, const LineLayoutTraversal::TextBox& textBox)
+static void writeTextBox(TextStream& ts, const RenderText& o, const LineLayoutTraversal::TextBoxIterator::BoxType& textBox)
{
auto rect = textBox.rect();
auto logicalRect = textBox.logicalRect();
Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp (250518 => 250519)
--- trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp 2019-09-30 15:55:37 UTC (rev 250519)
@@ -183,31 +183,6 @@
}
}
-IntRect computeBoundingBox(const RenderObject& renderer, const Layout& layout)
-{
- auto& resolver = layout.runResolver();
- FloatRect boundingBoxRect;
- for (auto run : resolver.rangeForRenderer(renderer)) {
- FloatRect rect = run.rect();
- if (boundingBoxRect == FloatRect())
- boundingBoxRect = rect;
- else
- boundingBoxRect.uniteEvenIfEmpty(rect);
- }
- return enclosingIntRect(boundingBoxRect);
-}
-
-Vector<IntRect> collectAbsoluteRects(const RenderObject& renderer, const Layout& layout, const LayoutPoint& accumulatedOffset)
-{
- Vector<IntRect> rects;
- auto& resolver = layout.runResolver();
- for (auto run : resolver.rangeForRenderer(renderer)) {
- FloatRect rect = run.rect();
- rects.append(enclosingIntRect(FloatRect(accumulatedOffset + rect.location(), rect.size())));
- }
- return rects;
-}
-
Vector<FloatQuad> collectAbsoluteQuads(const RenderObject& renderer, const Layout& layout, bool* wasFixed)
{
Vector<FloatQuad> quads;
@@ -262,11 +237,6 @@
return quads;
}
-const RenderObject& rendererForPosition(const FlowContents& flowContents, unsigned position)
-{
- return flowContents.segmentForPosition(position).renderer;
-}
-
void simpleLineLayoutWillBeDeleted(const Layout& layout)
{
for (unsigned i = 0; i < layout.runCount(); ++i)
Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.h (250518 => 250519)
--- trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.h 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.h 2019-09-30 15:55:37 UTC (rev 250519)
@@ -49,9 +49,6 @@
bool hitTestFlow(const RenderBlockFlow&, const Layout&, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
void collectFlowOverflow(RenderBlockFlow&, const Layout&);
-IntRect computeBoundingBox(const RenderObject&, const Layout&);
-
-Vector<IntRect> collectAbsoluteRects(const RenderObject&, const Layout&, const LayoutPoint& accumulatedOffset);
Vector<FloatQuad> collectAbsoluteQuads(const RenderObject&, const Layout&, bool* wasFixed);
unsigned textOffsetForPoint(const LayoutPoint&, const RenderText&, const Layout&);
Vector<FloatQuad> collectAbsoluteQuadsForRange(const RenderObject&, unsigned start, unsigned end, const Layout&, bool* wasFixed);
@@ -62,8 +59,6 @@
bool canUseForLineBoxTree(RenderBlockFlow&, const Layout&);
void generateLineBoxTree(RenderBlockFlow&, const Layout&);
-const RenderObject& rendererForPosition(const FlowContents&, unsigned);
-
void simpleLineLayoutWillBeDeleted(const Layout&);
#if ENABLE(TREE_DEBUGGING)
Modified: trunk/Source/WebCore/rendering/line/LineLayoutTraversal.cpp (250518 => 250519)
--- trunk/Source/WebCore/rendering/line/LineLayoutTraversal.cpp 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/rendering/line/LineLayoutTraversal.cpp 2019-09-30 15:55:37 UTC (rev 250519)
@@ -26,180 +26,11 @@
#include "config.h"
#include "LineLayoutTraversal.h"
-#include "InlineTextBox.h"
-#include "RenderText.h"
-#include "SimpleLineLayoutResolver.h"
+#include "RenderLineBreak.h"
namespace WebCore {
namespace LineLayoutTraversal {
-FloatRect TextBox::rect() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).rect();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->frameRect();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-FloatRect TextBox::logicalRect() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).rect();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->logicalFrameRect();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-bool TextBox::hasHyphen() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).hasHyphen();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->hasHyphen();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-bool TextBox::isLeftToRightDirection() const
-{
- auto simple = [](const TextBoxIterator::SimplePath&) {
- return true;
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->isLeftToRightDirection();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-bool TextBox::dirOverride() const
-{
- auto simple = [](const TextBoxIterator::SimplePath&) {
- return false;
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->dirOverride();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-StringView TextBox::text() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).text();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return StringView(path.inlineTextBox->renderer().text()).substring(path.inlineTextBox->start(), path.inlineTextBox->len());
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-bool TextBox::isLineBreak() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).isLineBreak();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->isLineBreak();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-unsigned TextBox::localStartOffset() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).localStart();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->start();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-unsigned TextBox::localEndOffset() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).localEnd();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->end();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-unsigned TextBox::length() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- return (*path.iterator).end() - (*path.iterator).start();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return path.inlineTextBox->len();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-bool TextBox::isLastOnLine() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- auto next = path.iterator;
- ++next;
- return next == path.end || (*path.iterator).lineIndex() != (*next).lineIndex();
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- auto* next = path.nextInlineTextBoxInTextOrder();
- return !next || &path.inlineTextBox->root() != &next->root();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-bool TextBox::isLast() const
-{
- auto simple = [](const TextBoxIterator::SimplePath& path) {
- auto next = path.iterator;
- ++next;
- return next == path.end;
- };
-
- auto complex = [](const TextBoxIterator::ComplexPath& path) {
- return !path.nextInlineTextBoxInTextOrder();
- };
-
- return WTF::switchOn(iterator().m_pathVariant, simple, complex);
-}
-
-
-inline const TextBoxIterator& TextBox::iterator() const
-{
- return static_cast<const TextBoxIterator&>(*this);
-}
-
TextBoxIterator::TextBoxIterator(const InlineTextBox* inlineTextBox)
: m_pathVariant(ComplexPath { inlineTextBox, { } })
{
@@ -221,7 +52,7 @@
};
auto complex = [](ComplexPath& path) {
- path.inlineTextBox = path.inlineTextBox->nextTextBox();
+ path.inlineBox = path.inlineBox->nextTextBox();
};
WTF::switchOn(m_pathVariant, simple, complex);
@@ -236,7 +67,7 @@
return sortedInlineTextBoxes[sortedInlineTextBoxIndex + 1];
return nullptr;
}
- return inlineTextBox->nextTextBox();
+ return inlineBox->nextTextBox();
}
TextBoxIterator& TextBoxIterator::traverseNextInTextOrder()
@@ -246,7 +77,7 @@
};
auto complex = [](ComplexPath& path) {
- path.inlineTextBox = path.nextInlineTextBoxInTextOrder();
+ path.inlineBox = path.nextInlineTextBoxInTextOrder();
if (!path.sortedInlineTextBoxes.isEmpty())
++path.sortedInlineTextBoxIndex;
};
@@ -266,7 +97,7 @@
};
auto complex = [&](const ComplexPath& path) {
- return path.inlineTextBox == WTF::get<ComplexPath>(other.m_pathVariant).inlineTextBox;
+ return path.inlineBox == WTF::get<ComplexPath>(other.m_pathVariant).inlineBox;
};
return WTF::switchOn(m_pathVariant, simple, complex);
@@ -279,7 +110,7 @@
};
auto complex = [&](const ComplexPath& path) {
- return !path.inlineTextBox;
+ return !path.inlineBox;
};
return WTF::switchOn(m_pathVariant, simple, complex);
@@ -313,5 +144,39 @@
return { firstTextBoxFor(text) };
}
+ElementBoxIterator::ElementBoxIterator(const InlineElementBox* inlineElementBox)
+ : m_pathVariant(ComplexPath { inlineElementBox })
+{
}
+ElementBoxIterator::ElementBoxIterator(SimpleLineLayout::RunResolver::Iterator iterator, SimpleLineLayout::RunResolver::Iterator end)
+ : m_pathVariant(SimplePath { iterator, end })
+{
}
+
+bool ElementBoxIterator::atEnd() const
+{
+ auto simple = [&](const SimplePath& path) {
+ return path.iterator == path.end;
+ };
+
+ auto complex = [&](const ComplexPath& path) {
+ return !path.inlineBox;
+ };
+
+ return WTF::switchOn(m_pathVariant, simple, complex);
+}
+
+ElementBoxIterator elementBoxFor(const RenderLineBreak& renderElement)
+{
+ if (auto& parent = *renderElement.parent(); is<RenderBlockFlow>(parent)) {
+ if (auto* simpleLineLayout = downcast<RenderBlockFlow>(parent).simpleLineLayout()) {
+ auto range = simpleLineLayout->runResolver().rangeForRenderer(renderElement);
+ return { range.begin(), range.end() };
+ }
+ }
+
+ return ElementBoxIterator { renderElement.inlineBoxWrapper() };
+}
+
+}
+}
Modified: trunk/Source/WebCore/rendering/line/LineLayoutTraversal.h (250518 => 250519)
--- trunk/Source/WebCore/rendering/line/LineLayoutTraversal.h 2019-09-30 12:38:44 UTC (rev 250518)
+++ trunk/Source/WebCore/rendering/line/LineLayoutTraversal.h 2019-09-30 15:55:37 UTC (rev 250519)
@@ -26,6 +26,9 @@
#pragma once
#include "FloatRect.h"
+#include "InlineElementBox.h"
+#include "InlineTextBox.h"
+#include "RenderText.h"
#include "SimpleLineLayoutResolver.h"
#include <wtf/HashMap.h>
#include <wtf/IteratorRange.h>
@@ -34,7 +37,7 @@
namespace WebCore {
-class InlineTextBox;
+class RenderLineBreak;
class RenderText;
namespace LineLayoutTraversal {
@@ -44,17 +47,32 @@
struct EndIterator { };
-class TextBox {
+template<class Iterator>
+class Box {
public:
FloatRect rect() const;
FloatRect logicalRect() const;
- bool hasHyphen() const;
bool isLeftToRightDirection() const;
bool dirOverride() const;
+ bool isLineBreak() const;
+protected:
+ Box() = default;
+ Box(const Box&) = default;
+ Box(Box&&) = default;
+ ~Box() = default;
+ Box& operator=(const Box&) = default;
+ Box& operator=(Box&&) = default;
+
+ const Iterator& iterator() const;
+};
+
+template<class Iterator>
+class TextBox : public Box<Iterator> {
+public:
+ bool hasHyphen() const;
StringView text() const;
- bool isLineBreak() const;
// These offsets are relative to the text renderer (not flow).
unsigned localStartOffset() const;
@@ -72,16 +90,15 @@
TextBox& operator=(const TextBox&) = default;
TextBox& operator=(TextBox&&) = default;
-private:
- const TextBoxIterator& iterator() const;
+ using Box<Iterator>::iterator;
};
-class TextBoxIterator : private TextBox {
+class TextBoxIterator : private TextBox<TextBoxIterator> {
public:
TextBoxIterator() : m_pathVariant(ComplexPath { nullptr, { } }) { };
+
explicit TextBoxIterator(const InlineTextBox*);
TextBoxIterator(Vector<const InlineTextBox*>&& sorted, size_t index);
-
TextBoxIterator(SimpleLineLayout::RunResolver::Iterator, SimpleLineLayout::RunResolver::Iterator end);
TextBoxIterator& operator++() { return traverseNextInVisualOrder(); }
@@ -101,8 +118,11 @@
bool atEnd() const;
+ using BoxType = TextBox<TextBoxIterator>;
+
private:
- friend class TextBox;
+ friend class Box<TextBoxIterator>;
+ friend class TextBox<TextBoxIterator>;
struct SimplePath {
SimpleLineLayout::RunResolver::Iterator iterator;
@@ -109,7 +129,7 @@
SimpleLineLayout::RunResolver::Iterator end;
};
struct ComplexPath {
- const InlineTextBox* inlineTextBox;
+ const InlineTextBox* inlineBox;
Vector<const InlineTextBox*> sortedInlineTextBoxes;
size_t sortedInlineTextBoxIndex { 0 };
@@ -118,6 +138,35 @@
Variant<SimplePath, ComplexPath> m_pathVariant;
};
+class ElementBoxIterator : private Box<ElementBoxIterator> {
+public:
+ ElementBoxIterator() : m_pathVariant(ComplexPath { nullptr }) { };
+
+ explicit ElementBoxIterator(const InlineElementBox*);
+ ElementBoxIterator(SimpleLineLayout::RunResolver::Iterator, SimpleLineLayout::RunResolver::Iterator end);
+
+ explicit operator bool() const { return !atEnd(); }
+
+ const Box& operator*() const { return *this; }
+ const Box* operator->() const { return this; }
+
+ bool atEnd() const;
+
+ using BoxType = Box<ElementBoxIterator>;
+
+private:
+ friend class Box<ElementBoxIterator>;
+
+ struct SimplePath {
+ SimpleLineLayout::RunResolver::Iterator iterator;
+ SimpleLineLayout::RunResolver::Iterator end;
+ };
+ struct ComplexPath {
+ const InlineElementBox* inlineBox;
+ };
+ Variant<SimplePath, ComplexPath> m_pathVariant;
+};
+
class TextBoxRange {
public:
TextBoxRange(TextBoxIterator begin)
@@ -135,8 +184,175 @@
TextBoxIterator firstTextBoxFor(const RenderText&);
TextBoxIterator firstTextBoxInTextOrderFor(const RenderText&);
TextBoxRange textBoxesFor(const RenderText&);
+ElementBoxIterator elementBoxFor(const RenderLineBreak&);
-inline bool hasTextBoxes(const RenderText& text) { return !firstTextBoxFor(text).atEnd(); }
+// -----------------------------------------------
+template<class Iterator> inline FloatRect Box<Iterator>::rect() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).rect();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->frameRect();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
}
+
+template<class Iterator> inline FloatRect Box<Iterator>::logicalRect() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).rect();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->logicalFrameRect();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
}
+
+template<class Iterator> inline bool Box<Iterator>::isLeftToRightDirection() const
+{
+ auto simple = [](const typename Iterator::SimplePath&) {
+ return true;
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->isLeftToRightDirection();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline bool Box<Iterator>::dirOverride() const
+{
+ auto simple = [](const typename Iterator::SimplePath&) {
+ return false;
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->dirOverride();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline bool Box<Iterator>::isLineBreak() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).isLineBreak();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->isLineBreak();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline const Iterator& Box<Iterator>::iterator() const
+{
+ return static_cast<const Iterator&>(*this);
+}
+
+template<class Iterator> inline bool TextBox<Iterator>::hasHyphen() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).hasHyphen();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->hasHyphen();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline StringView TextBox<Iterator>::text() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).text();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return StringView(path.inlineBox->renderer().text()).substring(path.inlineBox->start(), path.inlineBox->len());
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline unsigned TextBox<Iterator>::localStartOffset() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).localStart();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->start();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline unsigned TextBox<Iterator>::localEndOffset() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).localEnd();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->end();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline unsigned TextBox<Iterator>::length() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ return (*path.iterator).end() - (*path.iterator).start();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return path.inlineBox->len();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline bool TextBox<Iterator>::isLastOnLine() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ auto next = path.iterator;
+ ++next;
+ return next == path.end || (*path.iterator).lineIndex() != (*next).lineIndex();
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ auto* next = path.nextInlineTextBoxInTextOrder();
+ return !next || &path.inlineBox->root() != &next->root();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+template<class Iterator> inline bool TextBox<Iterator>::isLast() const
+{
+ auto simple = [](const typename Iterator::SimplePath& path) {
+ auto next = path.iterator;
+ ++next;
+ return next == path.end;
+ };
+
+ auto complex = [](const typename Iterator::ComplexPath& path) {
+ return !path.nextInlineTextBoxInTextOrder();
+ };
+
+ return WTF::switchOn(iterator().m_pathVariant, simple, complex);
+}
+
+}
+}