| /* |
| * Copyright (C) 2018 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 "LayoutContext.h" |
| |
| #if ENABLE(LAYOUT_FORMATTING_CONTEXT) |
| |
| #include "BlockFormattingContext.h" |
| #include "BlockFormattingState.h" |
| #include "FlexFormattingContext.h" |
| #include "FlexFormattingState.h" |
| #include "InlineFormattingContext.h" |
| #include "InlineFormattingState.h" |
| #include "LayoutBox.h" |
| #include "LayoutBoxGeometry.h" |
| #include "LayoutContainerBox.h" |
| #include "LayoutPhase.h" |
| #include "LayoutTreeBuilder.h" |
| #include "RenderStyleConstants.h" |
| #include "RenderView.h" |
| #include "RuntimeEnabledFeatures.h" |
| #include "TableFormattingContext.h" |
| #include "TableFormattingState.h" |
| #include "TableWrapperBlockFormattingContext.h" |
| #include <wtf/IsoMallocInlines.h> |
| |
| namespace WebCore { |
| namespace Layout { |
| |
| WTF_MAKE_ISO_ALLOCATED_IMPL(LayoutContext); |
| |
| LayoutContext::LayoutContext(LayoutState& layoutState) |
| : m_layoutState(layoutState) |
| { |
| } |
| |
| void LayoutContext::layout(const LayoutSize& rootContentBoxSize) |
| { |
| // Set the geometry on the root. |
| // Note that we never layout the root box. It has to have an already computed geometry (in case of ICB, it's the view geometry). |
| // ICB establishes the initial BFC, but it does not live in a formatting context and while a non-ICB root(subtree layout) has to have a formatting context, |
| // we could not lay it out even if we wanted to since it's outside of this LayoutContext. |
| auto& boxGeometry = layoutState().geometryForRootBox(); |
| boxGeometry.setHorizontalMargin({ }); |
| boxGeometry.setVerticalMargin({ }); |
| boxGeometry.setBorder({ }); |
| boxGeometry.setPadding({ }); |
| boxGeometry.setLogicalTopLeft({ }); |
| boxGeometry.setContentBoxHeight(rootContentBoxSize.height()); |
| boxGeometry.setContentBoxWidth(rootContentBoxSize.width()); |
| |
| auto scope = PhaseScope { Phase::Type::Layout }; |
| layoutFormattingContextSubtree(m_layoutState.root()); |
| } |
| |
| |
| void LayoutContext::layoutFormattingContextSubtree(const ContainerBox& formattingContextRoot) |
| { |
| RELEASE_ASSERT(formattingContextRoot.establishesFormattingContext()); |
| if (!formattingContextRoot.hasChild()) |
| return; |
| |
| auto formattingContext = createFormattingContext(formattingContextRoot, layoutState()); |
| auto& boxGeometry = layoutState().geometryForBox(formattingContextRoot); |
| |
| if (formattingContextRoot.hasInFlowOrFloatingChild()) { |
| auto constraintsForInFlowContent = ConstraintsForInFlowContent { { boxGeometry.contentBoxLeft(), boxGeometry.contentBoxWidth() }, boxGeometry.contentBoxTop() }; |
| formattingContext->layoutInFlowContent(constraintsForInFlowContent); |
| } |
| |
| // FIXME: layoutFormattingContextSubtree() does not perform layout on the root, rather it lays out the root's content. |
| // It constructs an FC for descendant boxes and runs layout on them. The formattingContextRoot is laid out in the FC in which it lives (parent formatting context). |
| // It also means that the formattingContextRoot has to have a valid/clean geometry at this point. |
| { |
| auto constraints = ConstraintsForOutOfFlowContent { { boxGeometry.paddingBoxLeft(), boxGeometry.paddingBoxWidth() }, |
| { boxGeometry.paddingBoxTop(), boxGeometry.paddingBoxHeight() }, boxGeometry.contentBoxWidth() }; |
| formattingContext->layoutOutOfFlowContent(constraints); |
| } |
| } |
| |
| std::unique_ptr<FormattingContext> LayoutContext::createFormattingContext(const ContainerBox& formattingContextRoot, LayoutState& layoutState) |
| { |
| ASSERT(formattingContextRoot.establishesFormattingContext()); |
| if (formattingContextRoot.establishesInlineFormattingContext()) { |
| auto& inlineFormattingState = layoutState.ensureInlineFormattingState(formattingContextRoot); |
| return makeUnique<InlineFormattingContext>(formattingContextRoot, inlineFormattingState); |
| } |
| |
| if (formattingContextRoot.establishesBlockFormattingContext()) { |
| ASSERT(!formattingContextRoot.establishesInlineFormattingContext()); |
| auto& blockFormattingState = layoutState.ensureBlockFormattingState(formattingContextRoot); |
| if (formattingContextRoot.isTableWrapperBox()) |
| return makeUnique<TableWrapperBlockFormattingContext>(formattingContextRoot, blockFormattingState); |
| return makeUnique<BlockFormattingContext>(formattingContextRoot, blockFormattingState); |
| } |
| |
| if (formattingContextRoot.establishesFlexFormattingContext()) { |
| auto& flexFormattingState = layoutState.ensureFlexFormattingState(formattingContextRoot); |
| return makeUnique<FlexFormattingContext>(formattingContextRoot, flexFormattingState); |
| } |
| |
| if (formattingContextRoot.establishesTableFormattingContext()) { |
| auto& tableFormattingState = layoutState.ensureTableFormattingState(formattingContextRoot); |
| return makeUnique<TableFormattingContext>(formattingContextRoot, tableFormattingState); |
| } |
| |
| CRASH(); |
| } |
| |
| } |
| } |
| |
| #endif |