#include "config.h"
#include "InlineLineBox.h"
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "LayoutBoxGeometry.h"
#include "LayoutContainerBox.h"
namespace WebCore {
namespace Layout {
LineBox::InlineLevelBox::InlineLevelBox(const Box& layoutBox, InlineLayoutUnit logicalLeft, InlineLayoutSize logicalSize, Type type)
: m_layoutBox(makeWeakPtr(layoutBox))
, m_logicalRect({ }, logicalLeft, logicalSize.width(), logicalSize.height())
, m_type(type)
{
}
void LineBox::InlineLevelBox::setBaseline(InlineLayoutUnit baseline)
{
m_baseline = roundToInt(baseline);
}
void LineBox::InlineLevelBox::setDescent(InlineLayoutUnit descent)
{
m_descent = roundToInt(descent);
}
void LineBox::InlineLevelBox::setLayoutBounds(const LayoutBounds& layoutBounds)
{
m_layoutBounds = { InlineLayoutUnit(roundToInt(layoutBounds.ascent)), InlineLayoutUnit(roundToInt(layoutBounds.descent)) };
}
void LineBox::InlineLevelBox::setLogicalTop(InlineLayoutUnit logicalTop)
{
m_logicalRect.setTop(roundToInt(logicalTop));
}
void LineBox::InlineLevelBox::setLogicalHeight(InlineLayoutUnit logicalHeight)
{
m_logicalRect.setHeight(roundToInt(logicalHeight));
}
void LineBox::InlineLevelBox::setHasContent()
{
ASSERT(isInlineBox());
m_hasContent = true;
}
bool LineBox::InlineLevelBox::hasLineBoxRelativeAlignment() const
{
auto verticalAlignment = layoutBox().style().verticalAlign();
return verticalAlignment == VerticalAlign::Top || verticalAlignment == VerticalAlign::Bottom;
}
LineBox::LineBox(const InlineLayoutPoint& logicalTopleft, InlineLayoutUnit contentLogicalWidth, IsLineConsideredEmpty isLineConsideredEmpty, size_t numberOfRuns)
: m_logicalRect(logicalTopleft, InlineLayoutSize { contentLogicalWidth, { } })
, m_isConsideredEmpty(isLineConsideredEmpty == IsLineConsideredEmpty::Yes)
{
m_nonRootInlineLevelBoxList.reserveInitialCapacity(numberOfRuns);
m_inlineLevelBoxRectMap.reserveInitialCapacity(numberOfRuns);
}
void LineBox::addRootInlineBox(std::unique_ptr<InlineLevelBox>&& rootInlineBox)
{
std::exchange(m_rootInlineBox, WTFMove(rootInlineBox));
m_inlineLevelBoxRectMap.set(&m_rootInlineBox->layoutBox(), m_rootInlineBox.get());
}
void LineBox::addInlineLevelBox(std::unique_ptr<InlineLevelBox>&& inlineLevelBox)
{
m_hasInlineBox = m_hasInlineBox || inlineLevelBox->isInlineBox();
m_inlineLevelBoxRectMap.set(&inlineLevelBox->layoutBox(), inlineLevelBox.get());
m_nonRootInlineLevelBoxList.append(WTFMove(inlineLevelBox));
}
InlineRect LineBox::logicalRectForTextRun(const Line::Run& run) const
{
ASSERT(run.isText() || run.isLineBreak());
auto* parentInlineBox = &inlineLevelBoxForLayoutBox(run.layoutBox().parent());
ASSERT(parentInlineBox->isInlineBox());
auto& fontMetrics = parentInlineBox->style().fontMetrics();
auto runlogicalTop = parentInlineBox->logicalTop() + parentInlineBox->baseline() - fontMetrics.ascent();
while (parentInlineBox != m_rootInlineBox.get() && !parentInlineBox->hasLineBoxRelativeAlignment()) {
parentInlineBox = &inlineLevelBoxForLayoutBox(parentInlineBox->layoutBox().parent());
ASSERT(parentInlineBox->isInlineBox());
runlogicalTop += parentInlineBox->logicalTop();
}
InlineLayoutUnit logicalHeight = fontMetrics.height();
return { runlogicalTop, m_horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }) + run.logicalLeft(), run.logicalWidth(), logicalHeight };
}
InlineRect LineBox::logicalMarginRectForInlineLevelBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
{
auto logicalRect = [&] {
auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
auto inlineBoxLogicalRect = inlineBox->logicalRect();
if (inlineBox->hasLineBoxRelativeAlignment())
return inlineBoxLogicalRect;
if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) {
inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop());
return inlineBoxLogicalRect;
}
auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
ASSERT(inlineBox->isInlineBox());
inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
}
return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
}();
if (!layoutBox.isInlineBox())
return logicalRect;
auto verticalBorderAndPadding = boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu);
logicalRect.expandVertically(verticalBorderAndPadding);
logicalRect.moveVertically(-(boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0_lu)));
return logicalRect;
}
} }
#endif