blob: 75eae5e0d41e6c63a78740efb2f721066e7ef69f [file] [log] [blame]
/*
* Copyright (C) 2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "InlineIteratorBox.h"
#include "InlineIteratorLine.h"
#include "InlineIteratorTextBox.h"
#include "LayoutIntegrationLineLayout.h"
#include "RenderBlockFlow.h"
#include "RenderLineBreak.h"
#include "RenderView.h"
namespace WebCore {
namespace InlineIterator {
BoxIterator::BoxIterator(Box::PathVariant&& pathVariant)
: m_box(WTFMove(pathVariant))
{
}
BoxIterator::BoxIterator(const Box& run)
: m_box(run)
{
}
bool BoxIterator::operator==(const BoxIterator& other) const
{
if (atEnd() && other.atEnd())
return true;
return m_box.m_pathVariant == other.m_box.m_pathVariant;
}
bool BoxIterator::atEnd() const
{
return WTF::switchOn(m_box.m_pathVariant, [](auto& path) {
return path.atEnd();
});
}
LeafBoxIterator Box::nextOnLine() const
{
return LeafBoxIterator(*this).traverseNextOnLine();
}
LeafBoxIterator Box::previousOnLine() const
{
return LeafBoxIterator(*this).traversePreviousOnLine();
}
LeafBoxIterator Box::nextOnLineIgnoringLineBreak() const
{
return LeafBoxIterator(*this).traverseNextOnLineIgnoringLineBreak();
}
LeafBoxIterator Box::previousOnLineIgnoringLineBreak() const
{
return LeafBoxIterator(*this).traversePreviousOnLineIgnoringLineBreak();
}
LineIterator Box::line() const
{
return WTF::switchOn(m_pathVariant, [](const BoxLegacyPath& path) {
return LineIterator(LineIteratorLegacyPath(&path.rootInlineBox()));
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
, [](const BoxModernPath& path) {
return LineIterator(LineIteratorModernPath(path.inlineContent(), path.box().lineIndex()));
}
#endif
);
}
const RenderStyle& Box::style() const
{
return line()->isFirst() ? renderer().firstLineStyle() : renderer().style();
}
RenderObject::HighlightState Box::selectionState() const
{
if (isText()) {
auto& text = downcast<TextBox>(*this);
auto& renderer = text.renderer();
return renderer.view().selection().highlightStateForTextBox(renderer, text.selectableRange());
}
return renderer().selectionState();
}
LeafBoxIterator::LeafBoxIterator(Box::PathVariant&& pathVariant)
: BoxIterator(WTFMove(pathVariant))
{
}
LeafBoxIterator::LeafBoxIterator(const Box& run)
: BoxIterator(run)
{
}
LeafBoxIterator& LeafBoxIterator::traverseNextOnLine()
{
WTF::switchOn(m_box.m_pathVariant, [](auto& path) {
path.traverseNextOnLine();
});
return *this;
}
LeafBoxIterator& LeafBoxIterator::traversePreviousOnLine()
{
WTF::switchOn(m_box.m_pathVariant, [](auto& path) {
path.traversePreviousOnLine();
});
return *this;
}
LeafBoxIterator& LeafBoxIterator::traverseNextOnLineIgnoringLineBreak()
{
do {
traverseNextOnLine();
} while (!atEnd() && m_box.isLineBreak());
return *this;
}
LeafBoxIterator& LeafBoxIterator::traversePreviousOnLineIgnoringLineBreak()
{
do {
traversePreviousOnLine();
} while (!atEnd() && m_box.isLineBreak());
return *this;
}
LeafBoxIterator boxFor(const RenderLineBreak& renderer)
{
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (auto* lineLayout = LayoutIntegration::LineLayout::containing(renderer))
return lineLayout->boxFor(renderer);
#endif
return { BoxLegacyPath(renderer.inlineBoxWrapper()) };
}
LeafBoxIterator boxFor(const RenderBox& renderer)
{
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (auto* lineLayout = LayoutIntegration::LineLayout::containing(renderer))
return lineLayout->boxFor(renderer);
#endif
return { BoxLegacyPath(renderer.inlineBoxWrapper()) };
}
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
LeafBoxIterator boxFor(const LayoutIntegration::InlineContent& content, size_t boxIndex)
{
return { BoxModernPath { content, boxIndex } };
}
#endif
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
const BoxModernPath& Box::modernPath() const
{
return std::get<BoxModernPath>(m_pathVariant);
}
#endif
const BoxLegacyPath& Box::legacyPath() const
{
return std::get<BoxLegacyPath>(m_pathVariant);
}
}
}