#include "config.h"
#include "LayoutContext.h"
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "BlockFormattingContext.h"
#include "BlockFormattingState.h"
#include "BlockInvalidation.h"
#include "DisplayBox.h"
#include "InlineFormattingContext.h"
#include "InlineFormattingState.h"
#include "InlineInvalidation.h"
#include "Invalidation.h"
#include "LayoutBox.h"
#include "LayoutContainer.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
namespace Layout {
WTF_MAKE_ISO_ALLOCATED_IMPL(LayoutContext);
LayoutContext::LayoutContext()
{
}
void LayoutContext::initializeRoot(const Container& root, const LayoutSize& containerSize)
{
ASSERT(root.establishesFormattingContext());
m_root = makeWeakPtr(const_cast<Container&>(root));
auto& displayBox = createDisplayBox(root);
displayBox.setHorizontalMargin({ });
displayBox.setVerticalMargin({ });
displayBox.setVerticalNonCollapsedMargin({ });
displayBox.setBorder({ });
displayBox.setPadding({ });
displayBox.setContentBoxHeight(containerSize.height());
displayBox.setContentBoxWidth(containerSize.width());
displayBox.setTopLeft({ });
m_formattingContextRootListForLayout.add(&root);
}
void LayoutContext::updateLayout()
{
ASSERT(!m_formattingContextRootListForLayout.isEmpty());
for (auto* layoutRoot : m_formattingContextRootListForLayout)
layoutFormattingContextSubtree(*layoutRoot);
m_formattingContextRootListForLayout.clear();
}
void LayoutContext::layoutFormattingContextSubtree(const Box& layoutRoot)
{
RELEASE_ASSERT(layoutRoot.establishesFormattingContext());
auto formattingContext = this->formattingContext(layoutRoot);
auto& formattingState = establishedFormattingState(layoutRoot, *formattingContext);
formattingContext->layout(*this, formattingState);
formattingContext->layoutOutOfFlowDescendants(*this, layoutRoot);
}
Display::Box& LayoutContext::createDisplayBox(const Box& layoutBox)
{
std::unique_ptr<Display::Box> displayBox(new Display::Box(layoutBox.style()));
auto* displayBoxPtr = displayBox.get();
m_layoutToDisplayBox.add(&layoutBox, WTFMove(displayBox));
return *displayBoxPtr;
}
void LayoutContext::styleChanged(const Box& layoutBox, StyleDiff styleDiff)
{
auto& formattingState = formattingStateForBox(layoutBox);
const Container* invalidationRoot = nullptr;
if (is<BlockFormattingState>(formattingState))
invalidationRoot = BlockInvalidation::invalidate(layoutBox, styleDiff, *this, downcast<BlockFormattingState>(formattingState)).root;
else if (is<InlineFormattingState>(formattingState))
invalidationRoot = InlineInvalidation::invalidate(layoutBox, styleDiff, *this, downcast<InlineFormattingState>(formattingState)).root;
else
ASSERT_NOT_IMPLEMENTED_YET();
ASSERT(invalidationRoot);
m_formattingContextRootListForLayout.addVoid(invalidationRoot);
}
void LayoutContext::markNeedsUpdate(const Box&, OptionSet<UpdateType>)
{
}
FormattingState& LayoutContext::formattingStateForBox(const Box& layoutBox) const
{
auto& root = layoutBox.formattingContextRoot();
RELEASE_ASSERT(m_formattingStates.contains(&root));
return *m_formattingStates.get(&root);
}
FormattingState& LayoutContext::establishedFormattingState(const Box& formattingContextRoot, const FormattingContext& context)
{
return *m_formattingStates.ensure(&formattingContextRoot, [this, &context] {
return context.createFormattingState(context.createOrFindFloatingState(*this), *this);
}).iterator->value;
}
std::unique_ptr<FormattingContext> LayoutContext::formattingContext(const Box& formattingContextRoot)
{
if (formattingContextRoot.establishesBlockFormattingContext())
return std::make_unique<BlockFormattingContext>(formattingContextRoot);
if (formattingContextRoot.establishesInlineFormattingContext())
return std::make_unique<InlineFormattingContext>(formattingContextRoot);
ASSERT_NOT_IMPLEMENTED_YET();
return nullptr;
}
}
}
#endif