LayoutIntegrationRunIterator.cpp [plain text]
#include "config.h"
#include "LayoutIntegrationRunIterator.h"
#include "LayoutIntegrationLineIterator.h"
#include "LayoutIntegrationLineLayout.h"
#include "RenderBlockFlow.h"
#include "RenderLineBreak.h"
namespace WebCore {
namespace LayoutIntegration {
RunIterator::RunIterator(PathRun::PathVariant&& pathVariant)
: m_run(WTFMove(pathVariant))
{
}
bool RunIterator::operator==(const RunIterator& other) const
{
return m_run.m_pathVariant == other.m_run.m_pathVariant;
}
bool RunIterator::atEnd() const
{
return WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
return path.atEnd();
});
}
void RunIterator::setAtEnd()
{
WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
path.setAtEnd();
});
}
RunIterator RunIterator::nextOnLine() const
{
return RunIterator(*this).traverseNextOnLine();
}
RunIterator RunIterator::previousOnLine() const
{
return RunIterator(*this).traversePreviousOnLine();
}
RunIterator RunIterator::nextOnLineIgnoringLineBreak() const
{
return RunIterator(*this).traverseNextOnLineIgnoringLineBreak();
}
RunIterator RunIterator::previousOnLineIgnoringLineBreak() const
{
return RunIterator(*this).traversePreviousOnLineIgnoringLineBreak();
}
LineIterator RunIterator::line() const
{
return WTF::switchOn(m_run.m_pathVariant, [](const RunIteratorLegacyPath& path) {
return LineIterator(LineIteratorLegacyPath(&path.rootInlineBox()));
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
, [](const RunIteratorModernPath& path) {
return LineIterator(LineIteratorModernPath(*path.m_inlineContent, path.run().lineIndex()));
}
#endif
);
}
TextRunIterator::TextRunIterator(PathRun::PathVariant&& pathVariant)
: RunIterator(WTFMove(pathVariant))
{
}
TextRunIterator& TextRunIterator::traverseNextTextRun()
{
WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
path.traverseNextTextRun();
});
return *this;
}
TextRunIterator& TextRunIterator::traverseNextTextRunInTextOrder()
{
WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
path.traverseNextTextRunInTextOrder();
});
return *this;
}
RunIterator& RunIterator::traverseNextOnLine()
{
WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
path.traverseNextOnLine();
});
return *this;
}
RunIterator& RunIterator::traversePreviousOnLine()
{
WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
path.traversePreviousOnLine();
});
return *this;
}
RunIterator& RunIterator::traverseNextOnLineIgnoringLineBreak()
{
traverseNextOnLine();
if (!atEnd() && m_run.isLineBreak())
setAtEnd();
return *this;
}
RunIterator& RunIterator::traversePreviousOnLineIgnoringLineBreak()
{
traversePreviousOnLine();
if (!atEnd() && m_run.isLineBreak())
setAtEnd();
return *this;
}
RunIterator& RunIterator::traverseNextOnLineInLogicalOrder()
{
WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
path.traverseNextOnLineInLogicalOrder();
});
return *this;
}
RunIterator& RunIterator::traversePreviousOnLineInLogicalOrder()
{
WTF::switchOn(m_run.m_pathVariant, [](auto& path) {
path.traversePreviousOnLineInLogicalOrder();
});
return *this;
}
TextRunIterator firstTextRunFor(const RenderText& text)
{
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (auto* lineLayout = LineLayout::containing(text))
return lineLayout->textRunsFor(text);
#endif
return { RunIteratorLegacyPath { text.firstTextBox() } };
}
TextRunIterator firstTextRunInTextOrderFor(const RenderText& text)
{
if (text.firstTextBox() && text.containsReversedText()) {
Vector<const InlineBox*> sortedTextBoxes;
for (auto* textBox = text.firstTextBox(); textBox; textBox = textBox->nextTextBox())
sortedTextBoxes.append(textBox);
std::sort(sortedTextBoxes.begin(), sortedTextBoxes.end(), [](auto* a, auto* b) {
return InlineTextBox::compareByStart(downcast<InlineTextBox>(a), downcast<InlineTextBox>(b));
});
auto* first = sortedTextBoxes[0];
return { RunIteratorLegacyPath { first, WTFMove(sortedTextBoxes), 0 } };
}
return firstTextRunFor(text);
}
TextRunRange textRunsFor(const RenderText& text)
{
return { firstTextRunFor(text) };
}
RunIterator runFor(const RenderLineBreak& renderer)
{
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (auto* lineLayout = LineLayout::containing(renderer))
return lineLayout->runFor(renderer);
#endif
return { RunIteratorLegacyPath(renderer.inlineBoxWrapper()) };
}
RunIterator runFor(const RenderBox& renderer)
{
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (auto* lineLayout = LineLayout::containing(renderer))
return lineLayout->runFor(renderer);
#endif
return { RunIteratorLegacyPath(renderer.inlineBoxWrapper()) };
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
const RunIteratorModernPath& PathRun::modernPath() const
{
return WTF::get<RunIteratorModernPath>(m_pathVariant);
}
#endif
const RunIteratorLegacyPath& PathRun::legacyPath() const
{
return WTF::get<RunIteratorLegacyPath>(m_pathVariant);
}
}
}