[LFC][Floating] Simplify FloatingState::FloatItem class
[WebKit-https.git] / Source / WebCore / layout / floats / FloatingState.cpp
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "FloatingState.h"
28
29 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
30
31 #include "FormattingContext.h"
32 #include "LayoutBox.h"
33 #include "LayoutContainer.h"
34 #include "LayoutContext.h"
35 #include <wtf/IsoMallocInlines.h>
36
37 namespace WebCore {
38 namespace Layout {
39
40 WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingState);
41
42 FloatingState::FloatItem::FloatItem(const Box& layoutBox, const FloatingState& floatingState)
43     : m_layoutBox(makeWeakPtr(const_cast<Box&>(layoutBox)))
44     , m_absoluteDisplayBox(FormattingContext::mapBoxToAncestor(floatingState.layoutContext(), layoutBox, downcast<Container>(floatingState.root())))
45 {
46 }
47
48 FloatingState::FloatingState(LayoutContext& layoutContext, const Box& formattingContextRoot)
49     : m_layoutContext(layoutContext)
50     , m_formattingContextRoot(makeWeakPtr(const_cast<Box&>(formattingContextRoot)))
51 {
52 }
53
54 #ifndef NDEBUG
55 static bool belongsToThisFloatingContext(const Box& layoutBox, const Box& floatingStateRoot)
56 {
57     auto& formattingContextRoot = layoutBox.formattingContextRoot();
58     if (&formattingContextRoot == &floatingStateRoot)
59         return true;
60
61     // Maybe the layout box belongs to an inline formatting context that inherits the floating state from the parent (block) formatting context. 
62     if (!formattingContextRoot.establishesInlineFormattingContext())
63         return false;
64
65     return &formattingContextRoot.formattingContextRoot() == &floatingStateRoot;
66 }
67 #endif
68
69 void FloatingState::remove(const Box& layoutBox)
70 {
71     for (size_t index = 0; index < m_floats.size(); ++index) {
72         if (m_floats[index] == layoutBox) {
73             m_floats.remove(index);
74             return;
75         }
76     }
77     ASSERT_NOT_REACHED();
78 }
79
80 void FloatingState::append(const Box& layoutBox)
81 {
82     ASSERT(is<Container>(*m_formattingContextRoot));
83     ASSERT(belongsToThisFloatingContext(layoutBox, *m_formattingContextRoot));
84
85     // Floating state should hold boxes with computed position/size.
86     ASSERT(m_layoutContext.displayBoxForLayoutBox(layoutBox));
87     ASSERT(is<Container>(*m_formattingContextRoot));
88
89     m_floats.append({ layoutBox, *this });
90 }
91
92 std::optional<LayoutUnit> FloatingState::bottom(const Box& formattingContextRoot, Clear type) const
93 {
94     if (m_floats.isEmpty())
95         return { };
96
97     // TODO: Currently this is only called once for each formatting context root with floats per layout.
98     // Cache the value if we end up calling it more frequently (and update it at append/remove).
99     std::optional<LayoutUnit> bottom;
100     for (auto& floatItem : m_floats) {
101         // Ignore floats from other formatting contexts when the floating state is inherited.
102         if (!floatItem.inFormattingContext(formattingContextRoot))
103             continue;
104
105         if ((type == Clear::Left && !floatItem.isLeftPositioned())
106             || (type == Clear::Right && floatItem.isLeftPositioned()))
107             continue;
108
109         auto floatsBottom = floatItem.rectWithMargin().bottom();
110         if (bottom) {
111             bottom = std::max(*bottom, floatsBottom);
112             continue;
113         }
114         bottom = floatsBottom;
115     }
116     return bottom;
117 }
118
119 }
120 }
121 #endif