blob: 123683bed896345d202f29e3b58edc59cc28a7e2 [file] [log] [blame]
/*
* Copyright (C) 2003-2017 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "LegacyRootInlineBox.h"
#include "BidiResolver.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
#include "LegacyInlineTextBox.h"
#include "LocalFrame.h"
#include "LogicalSelectionOffsetCaches.h"
#include "PaintInfo.h"
#include "RenderBlockInlines.h"
#include "RenderBoxInlines.h"
#include "RenderFragmentedFlow.h"
#include "RenderInline.h"
#include "RenderLayoutState.h"
#include "RenderView.h"
#include <wtf/TZoneMallocInlines.h>
namespace WebCore {
WTF_MAKE_TZONE_ALLOCATED_IMPL(LegacyRootInlineBox);
struct SameSizeAsLegacyRootInlineBox : LegacyInlineFlowBox, CanMakeWeakPtr<LegacyRootInlineBox>, CanMakeCheckedPtr<SameSizeAsLegacyRootInlineBox> {
WTF_MAKE_STRUCT_TZONE_ALLOCATED(SameSizeAsLegacyRootInlineBox);
WTF_STRUCT_OVERRIDE_DELETE_FOR_CHECKED_PTR(SameSizeAsLegacyRootInlineBox);
int layoutUnits[4];
};
WTF_MAKE_STRUCT_TZONE_ALLOCATED_IMPL(SameSizeAsLegacyRootInlineBox);
static_assert(sizeof(LegacyRootInlineBox) == sizeof(SameSizeAsLegacyRootInlineBox), "LegacyRootInlineBox should stay small");
#if !ASSERT_ENABLED
static_assert(sizeof(SingleThreadWeakPtr<RenderObject>) == sizeof(void*), "WeakPtr should be same size as raw pointer");
#endif
LegacyRootInlineBox::LegacyRootInlineBox(RenderBlockFlow& block)
: LegacyInlineFlowBox(block)
{
setIsHorizontal(block.isHorizontalWritingMode());
}
LegacyRootInlineBox::~LegacyRootInlineBox()
{
}
void LegacyRootInlineBox::adjustPosition(float dx, float dy)
{
LegacyInlineFlowBox::adjustPosition(dx, dy);
LayoutUnit blockDirectionDelta { isHorizontal() ? dy : dx }; // The block direction delta is a LayoutUnit.
m_lineTop += blockDirectionDelta;
m_lineBottom += blockDirectionDelta;
m_lineBoxTop += blockDirectionDelta;
m_lineBoxBottom += blockDirectionDelta;
}
RenderObject::HighlightState LegacyRootInlineBox::selectionState() const
{
// Walk over all of the selected boxes.
RenderObject::HighlightState state = RenderObject::HighlightState::None;
for (auto* box = firstLeafDescendant(); box; box = box->nextLeafOnLine()) {
RenderObject::HighlightState boxState = box->selectionState();
if ((boxState == RenderObject::HighlightState::Start && state == RenderObject::HighlightState::End)
|| (boxState == RenderObject::HighlightState::End && state == RenderObject::HighlightState::Start))
state = RenderObject::HighlightState::Both;
else if (state == RenderObject::HighlightState::None || ((boxState == RenderObject::HighlightState::Start || boxState == RenderObject::HighlightState::End)
&& (state == RenderObject::HighlightState::None || state == RenderObject::HighlightState::Inside)))
state = boxState;
else if (boxState == RenderObject::HighlightState::None && state == RenderObject::HighlightState::Start) {
// We are past the end of the selection.
state = RenderObject::HighlightState::Both;
}
if (state == RenderObject::HighlightState::Both)
break;
}
return state;
}
const LegacyInlineBox* LegacyRootInlineBox::firstSelectedBox() const
{
for (auto* box = firstLeafDescendant(); box; box = box->nextLeafOnLine()) {
if (box->selectionState() != RenderObject::HighlightState::None)
return box;
}
return nullptr;
}
const LegacyInlineBox* LegacyRootInlineBox::lastSelectedBox() const
{
for (auto* box = lastLeafDescendant(); box; box = box->previousLeafOnLine()) {
if (box->selectionState() != RenderObject::HighlightState::None)
return box;
}
return nullptr;
}
LayoutUnit LegacyRootInlineBox::selectionTop() const
{
LayoutUnit selectionTop = m_lineTop;
if (renderer().style().writingMode().isLineInverted())
return selectionTop;
LayoutUnit prevBottom;
if (auto* previousBox = prevRootBox())
prevBottom = previousBox->selectionBottom();
else
prevBottom = selectionTop;
return prevBottom;
}
LayoutUnit LegacyRootInlineBox::selectionTopAdjustedForPrecedingBlock() const
{
return blockFlow().adjustEnclosingTopForPrecedingBlock(selectionTop());
}
LayoutUnit LegacyRootInlineBox::selectionBottom() const
{
LayoutUnit selectionBottom = m_lineBottom;
if (!renderer().style().writingMode().isLineInverted() || !nextRootBox())
return selectionBottom;
return nextRootBox()->selectionTop();
}
RenderBlockFlow& LegacyRootInlineBox::blockFlow() const
{
return downcast<RenderBlockFlow>(renderer());
}
void LegacyRootInlineBox::removeLineBoxFromRenderObject()
{
}
LayoutUnit LegacyRootInlineBox::lineBoxWidth() const
{
return blockFlow().availableLogicalWidthForLine(lineBoxTop(), lineBoxHeight());
}
#if ENABLE(TREE_DEBUGGING)
void LegacyRootInlineBox::outputLineBox(WTF::TextStream& stream, bool mark, int depth) const
{
stream << "-------- --";
int printedCharacters = 0;
while (++printedCharacters <= depth * 2)
stream << " ";
stream << "Line: (top: " << lineTop() << " bottom: " << lineBottom() << ") with leading (top: " << lineBoxTop() << " bottom: " << lineBoxBottom() << ")";
stream.nextLine();
LegacyInlineBox::outputLineBox(stream, mark, depth);
}
ASCIILiteral LegacyRootInlineBox::boxName() const
{
return "RootInlineBox"_s;
}
#endif
} // namespace WebCore