LineLayoutTraversal.cpp [plain text]
#include "config.h"
#include "LineLayoutTraversal.h"
#include "LayoutIntegrationLineLayout.h"
#include "RenderLineBreak.h"
namespace WebCore {
namespace LineLayoutTraversal {
TextBoxIterator::TextBoxIterator(Box::PathVariant&& pathVariant)
: m_textBox(WTFMove(pathVariant))
{
}
TextBoxIterator& TextBoxIterator::traverseNextInVisualOrder()
{
WTF::switchOn(m_textBox.m_pathVariant, [](auto& path) {
path.traverseNextTextBoxInVisualOrder();
});
return *this;
}
TextBoxIterator& TextBoxIterator::traverseNextInTextOrder()
{
WTF::switchOn(m_textBox.m_pathVariant, [](auto& path) {
path.traverseNextTextBoxInTextOrder();
});
return *this;
}
bool TextBoxIterator::operator==(const TextBoxIterator& other) const
{
if (m_textBox.m_pathVariant.index() != other.m_textBox.m_pathVariant.index())
return false;
return WTF::switchOn(m_textBox.m_pathVariant, [&](const auto& path) {
return path == WTF::get<std::decay_t<decltype(path)>>(other.m_textBox.m_pathVariant);
});
}
bool TextBoxIterator::atEnd() const
{
return WTF::switchOn(m_textBox.m_pathVariant, [](auto& path) {
return path.atEnd();
});
}
static const RenderBlockFlow* lineLayoutSystemFlowForRenderer(const RenderObject& renderer)
{
if (!is<RenderBlockFlow>(*renderer.parent()))
return nullptr;
return downcast<RenderBlockFlow>(renderer.parent());
}
TextBoxIterator firstTextBoxFor(const RenderText& text)
{
if (auto* flow = lineLayoutSystemFlowForRenderer(text)) {
if (auto* simpleLineLayout = flow->simpleLineLayout()) {
auto range = simpleLineLayout->runResolver().rangeForRenderer(text);
return { SimplePath { range.begin(), range.end() } };
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (auto* layoutFormattingContextLineLayout = flow->layoutFormattingContextLineLayout())
return layoutFormattingContextLineLayout->textBoxesFor(text);
#endif
}
return { ComplexPath { text.firstTextBox() } };
}
TextBoxIterator firstTextBoxInTextOrderFor(const RenderText& text)
{
if (text.firstTextBox() && text.containsReversedText()) {
Vector<const InlineTextBox*> sortedTextBoxes;
for (auto* textBox = text.firstTextBox(); textBox; textBox = textBox->nextTextBox())
sortedTextBoxes.append(textBox);
std::sort(sortedTextBoxes.begin(), sortedTextBoxes.end(), InlineTextBox::compareByStart);
auto* first = sortedTextBoxes[0];
return { ComplexPath { first, WTFMove(sortedTextBoxes), 0 } };
}
return firstTextBoxFor(text);
}
TextBoxRange textBoxesFor(const RenderText& text)
{
return { firstTextBoxFor(text) };
}
ElementBoxIterator::ElementBoxIterator(Box::PathVariant&& pathVariant)
: m_box(WTFMove(pathVariant))
{
}
bool ElementBoxIterator::atEnd() const
{
return WTF::switchOn(m_box.m_pathVariant, [](auto& path) {
return path.atEnd();
});
}
ElementBoxIterator elementBoxFor(const RenderLineBreak& renderElement)
{
if (auto* flow = lineLayoutSystemFlowForRenderer(renderElement)) {
if (auto* simpleLineLayout = flow->simpleLineLayout()) {
auto range = simpleLineLayout->runResolver().rangeForRenderer(renderElement);
return { SimplePath(range.begin(), range.end()) };
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (auto* layoutFormattingContextLineLayout = flow->layoutFormattingContextLineLayout())
return layoutFormattingContextLineLayout->elementBoxFor(renderElement);
#endif
}
return { ComplexPath(renderElement.inlineBoxWrapper()) };
}
}
}