#include "config.h"
#include "FloatAvoider.h"
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "LayoutBox.h"
#include "LayoutContainerBox.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
namespace Layout {
WTF_MAKE_ISO_ALLOCATED_IMPL(FloatAvoider);
FloatAvoider::FloatAvoider(const Box& layoutBox, LayoutPoint absoluteTopLeft, LayoutUnit borderBoxWidth, const Edges& margin, HorizontalEdges containingBlockAbsoluteContentBox)
: m_layoutBox(makeWeakPtr(layoutBox))
, m_absoluteTopLeft(absoluteTopLeft)
, m_borderBoxWidth(borderBoxWidth)
, m_margin(margin)
, m_containingBlockAbsoluteContentBox(containingBlockAbsoluteContentBox)
{
ASSERT(m_layoutBox->establishesBlockFormattingContext());
m_absoluteTopLeft.setX(initialHorizontalPosition());
}
void FloatAvoider::setHorizontalPosition(LayoutUnit horizontalPosition)
{
if (isLeftAligned() && isFloatingBox())
horizontalPosition += marginStart();
if (!isLeftAligned()) {
horizontalPosition -= borderBoxWidth();
if (isFloatingBox())
horizontalPosition -= marginEnd();
}
auto constrainedByContainingBlock = [&] {
if (isLeftAligned())
return std::max(m_containingBlockAbsoluteContentBox.left + marginStart(), horizontalPosition);
return std::min(horizontalPosition, m_containingBlockAbsoluteContentBox.right - marginBoxWidth() + marginStart());
}();
m_absoluteTopLeft.setX(constrainedByContainingBlock);
}
void FloatAvoider::setVerticalPosition(LayoutUnit verticalPosition)
{
if (isFloatingBox())
verticalPosition += marginBefore();
m_absoluteTopLeft.setY(verticalPosition);
}
LayoutUnit FloatAvoider::initialHorizontalPosition() const
{
if (isLeftAligned())
return { m_containingBlockAbsoluteContentBox.left + marginStart() };
return { m_containingBlockAbsoluteContentBox.right - marginEnd() - borderBoxWidth() };
}
bool FloatAvoider::overflowsContainingBlock() const
{
auto left = m_absoluteTopLeft.x() - marginStart();
if (m_containingBlockAbsoluteContentBox.left > left)
return true;
auto right = left + marginBoxWidth();
return m_containingBlockAbsoluteContentBox.right < right;
}
}
}
#endif