2019-09-20 13:36:00 +00:00
/*
* 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"
2020-09-16 14:05:50 +00:00
# include "FlexFormattingContext.h"
# include "FlexFormattingState.h"
2019-09-20 13:36:00 +00:00
# include "InlineFormattingContext.h"
# include "InlineFormattingState.h"
2019-11-13 18:39:44 +00:00
# include "InvalidationContext.h"
# include "InvalidationState.h"
2019-09-20 13:36:00 +00:00
# include "LayoutBox.h"
2020-09-15 05:52:14 +00:00
# include "LayoutBoxGeometry.h"
2020-02-12 01:08:08 +00:00
# include "LayoutContainerBox.h"
2019-09-20 13:36:00 +00:00
# include "LayoutPhase.h"
# include "LayoutTreeBuilder.h"
2019-11-13 18:39:44 +00:00
# include "RenderStyleConstants.h"
2019-09-20 13:36:00 +00:00
# include "RenderView.h"
2020-01-09 17:36:59 +00:00
# include "RuntimeEnabledFeatures.h"
2019-09-20 13:36:00 +00:00
# include "TableFormattingContext.h"
# include "TableFormattingState.h"
2020-05-17 16:17:45 +00:00
# include "TableWrapperBlockFormattingContext.h"
2019-09-20 13:36:00 +00:00
# include <wtf/IsoMallocInlines.h>
namespace WebCore {
namespace Layout {
WTF_MAKE_ISO_ALLOCATED_IMPL ( LayoutContext ) ;
LayoutContext : : LayoutContext ( LayoutState & layoutState )
: m_layoutState ( layoutState )
{
}
2019-11-17 21:02:49 +00:00
void LayoutContext : : layout ( const LayoutSize & rootContentBoxSize , InvalidationState & invalidationState )
2019-09-20 13:36:00 +00:00
{
2019-11-17 21:02:49 +00:00
// 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.
2020-09-15 05:52:14 +00:00
auto & boxGeometry = layoutState ( ) . geometryForRootBox ( ) ;
boxGeometry . setHorizontalMargin ( { } ) ;
boxGeometry . setVerticalMargin ( { } ) ;
boxGeometry . setBorder ( { } ) ;
boxGeometry . setPadding ( { } ) ;
2020-09-16 20:58:12 +00:00
boxGeometry . setLogicalTopLeft ( { } ) ;
2020-09-15 05:52:14 +00:00
boxGeometry . setContentBoxHeight ( rootContentBoxSize . height ( ) ) ;
boxGeometry . setContentBoxWidth ( rootContentBoxSize . width ( ) ) ;
2019-11-27 21:41:57 +00:00
2019-12-03 10:51:46 +00:00
layoutWithPreparedRootGeometry ( invalidationState ) ;
}
void LayoutContext : : layoutWithPreparedRootGeometry ( InvalidationState & invalidationState )
{
PhaseScope scope ( Phase : : Type : : Layout ) ;
2019-11-27 21:41:57 +00:00
auto & formattingContextRootsForLayout = invalidationState . formattingContextRoots ( ) ;
// When invalidation is empty, we assume constraint mutation and start running layout on the context root. Layout logic should be able to figure out the damage.
if ( formattingContextRootsForLayout . computesEmpty ( ) )
return layoutFormattingContextSubtree ( m_layoutState . root ( ) , invalidationState ) ;
2019-11-13 18:39:44 +00:00
for ( auto & formattingContextRoot : formattingContextRootsForLayout )
2019-11-14 19:42:50 +00:00
layoutFormattingContextSubtree ( formattingContextRoot , invalidationState ) ;
2019-09-20 13:36:00 +00:00
}
2020-02-12 01:08:08 +00:00
void LayoutContext : : layoutFormattingContextSubtree ( const ContainerBox & formattingContextRoot , InvalidationState & invalidationState )
2019-09-20 13:36:00 +00:00
{
2019-11-13 18:39:44 +00:00
RELEASE_ASSERT ( formattingContextRoot . establishesFormattingContext ( ) ) ;
2020-02-20 16:44:39 +00:00
if ( ! formattingContextRoot . hasChild ( ) )
return ;
2019-11-13 18:39:44 +00:00
auto formattingContext = createFormattingContext ( formattingContextRoot , layoutState ( ) ) ;
2020-09-15 05:52:14 +00:00
auto & boxGeometry = layoutState ( ) . geometryForBox ( formattingContextRoot ) ;
2020-01-09 17:36:59 +00:00
2020-02-17 15:53:41 +00:00
if ( formattingContextRoot . hasInFlowOrFloatingChild ( ) ) {
2021-06-01 02:41:01 +00:00
auto constraintsForInFlowContent = ConstraintsForInFlowContent { { boxGeometry . contentBoxLeft ( ) , boxGeometry . contentBoxWidth ( ) } , boxGeometry . contentBoxTop ( ) } ;
2020-04-28 14:44:42 +00:00
formattingContext - > layoutInFlowContent ( invalidationState , constraintsForInFlowContent ) ;
2020-02-17 15:53:41 +00:00
}
2020-01-09 17:36:59 +00:00
// 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.
2020-01-21 16:07:21 +00:00
{
2021-05-16 15:57:35 +00:00
auto constraints = ConstraintsForOutOfFlowContent { { boxGeometry . paddingBoxLeft ( ) , boxGeometry . paddingBoxWidth ( ) } ,
2020-09-15 05:52:14 +00:00
{ boxGeometry . paddingBoxTop ( ) , boxGeometry . paddingBoxHeight ( ) } , boxGeometry . contentBoxWidth ( ) } ;
2020-04-28 15:25:11 +00:00
formattingContext - > layoutOutOfFlowContent ( invalidationState , constraints ) ;
2020-01-09 17:36:59 +00:00
}
2019-09-20 13:36:00 +00:00
}
2020-02-12 01:08:08 +00:00
std : : unique_ptr < FormattingContext > LayoutContext : : createFormattingContext ( const ContainerBox & formattingContextRoot , LayoutState & layoutState )
2019-09-20 13:36:00 +00:00
{
ASSERT ( formattingContextRoot . establishesFormattingContext ( ) ) ;
if ( formattingContextRoot . establishesInlineFormattingContext ( ) ) {
2020-01-21 21:08:55 +00:00
auto & inlineFormattingState = layoutState . ensureInlineFormattingState ( formattingContextRoot ) ;
2019-09-20 13:36:00 +00:00
return makeUnique < InlineFormattingContext > ( formattingContextRoot , inlineFormattingState ) ;
}
if ( formattingContextRoot . establishesBlockFormattingContext ( ) ) {
2020-02-09 02:51:46 +00:00
ASSERT ( ! formattingContextRoot . establishesInlineFormattingContext ( ) ) ;
2020-01-21 21:08:55 +00:00
auto & blockFormattingState = layoutState . ensureBlockFormattingState ( formattingContextRoot ) ;
2020-05-17 16:17:45 +00:00
if ( formattingContextRoot . isTableWrapperBox ( ) )
return makeUnique < TableWrapperBlockFormattingContext > ( formattingContextRoot , blockFormattingState ) ;
2019-09-20 13:36:00 +00:00
return makeUnique < BlockFormattingContext > ( formattingContextRoot , blockFormattingState ) ;
}
2020-09-16 14:05:50 +00:00
if ( formattingContextRoot . establishesFlexFormattingContext ( ) ) {
auto & flexFormattingState = layoutState . ensureFlexFormattingState ( formattingContextRoot ) ;
return makeUnique < FlexFormattingContext > ( formattingContextRoot , flexFormattingState ) ;
}
2019-09-20 13:36:00 +00:00
if ( formattingContextRoot . establishesTableFormattingContext ( ) ) {
2020-01-21 21:08:55 +00:00
auto & tableFormattingState = layoutState . ensureTableFormattingState ( formattingContextRoot ) ;
2019-09-20 13:36:00 +00:00
return makeUnique < TableFormattingContext > ( formattingContextRoot , tableFormattingState ) ;
}
CRASH ( ) ;
}
}
}
# endif