d1f10299b547611ceaee85444373d22f54c82f0a
[WebKit-https.git] / Source / WebCore / rendering / LayoutState.h
1 /*
2  * Copyright (C) 2007, 2013 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #include "LayoutRect.h"
29 #include <wtf/Noncopyable.h>
30
31 namespace WebCore {
32
33 class LayoutContext;
34 class RenderBlockFlow;
35 class RenderBox;
36 class RenderElement;
37 class RenderFragmentedFlow;
38 class RenderObject;
39
40 class LayoutState {
41     WTF_MAKE_NONCOPYABLE(LayoutState); WTF_MAKE_FAST_ALLOCATED;
42
43 public:
44     LayoutState()
45         : m_clipped(false)
46         , m_isPaginated(false)
47         , m_pageLogicalHeightChanged(false)
48 #if !ASSERT_DISABLED
49         , m_layoutDeltaXSaturated(false)
50         , m_layoutDeltaYSaturated(false)
51 #endif
52     {
53     }
54
55     LayoutState(std::unique_ptr<LayoutState> ancestor, RenderBox&, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged);
56     explicit LayoutState(RenderElement&);
57
58     bool isPaginated() const { return m_isPaginated; }
59     void setIsPaginated() { m_isPaginated = true; }
60     void clearPaginationInformation();
61
62     // The page logical offset is the object's offset from the top of the page in the page progression
63     // direction (so an x-offset in vertical text and a y-offset for horizontal text).
64     LayoutUnit pageLogicalOffset(RenderBox*, LayoutUnit childLogicalOffset) const;
65     
66     void setPageLogicalHeight(LayoutUnit logicalHeight) { m_pageLogicalHeight = logicalHeight; }
67     LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; }
68     bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
69
70     RenderBlockFlow* lineGrid() const { return m_lineGrid; }
71     LayoutSize lineGridOffset() const { return m_lineGridOffset; }
72     LayoutSize lineGridPaginationOrigin() const { return m_lineGridPaginationOrigin; }
73
74     LayoutSize paintOffset() const { return m_paintOffset; }
75     LayoutSize layoutOffset() const { return m_layoutOffset; }
76
77     LayoutSize pageOffset() const { return m_pageOffset; }
78     void setLineGridPaginationOrigin(const LayoutSize& origin) { m_lineGridPaginationOrigin = origin; }
79     
80     bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); }
81
82     RenderFragmentedFlow* currentRenderFragmentedFlow() const { return m_currentRenderFragmentedFlow; }
83     void setCurrentRenderFragmentedFlow(RenderFragmentedFlow* fragmentedFlow) { m_currentRenderFragmentedFlow = fragmentedFlow; }
84 #ifndef NDEBUG
85     RenderElement* renderer() const { return m_renderer; }
86 #endif
87     LayoutRect clipRect() const { return m_clipRect; }
88     bool isClipped() const { return m_clipped; }
89
90     void addLayoutDelta(LayoutSize);
91     LayoutSize layoutDelta() const { return m_layoutDelta; }
92 #if !ASSERT_DISABLED
93     bool layoutDeltaMatches(LayoutSize);
94 #endif
95
96     // FIXME: webkit.org/b/179408 LayoutContext should own the stack of LayoutState objects
97     std::unique_ptr<LayoutState> m_ancestor;
98
99 private:
100     void computeOffsets(RenderBox&, LayoutSize offset);
101     void computeClipRect(RenderBox&);
102     void computePaginationInformation(RenderBox&, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged);
103     void propagateLineGridInfo(RenderBox&);
104     void establishLineGrid(RenderBlockFlow&);
105
106     // Do not add anything apart from bitfields. See https://bugs.webkit.org/show_bug.cgi?id=100173
107     bool m_clipped : 1;
108     bool m_isPaginated : 1;
109     // If our page height has changed, this will force all blocks to relayout.
110     bool m_pageLogicalHeightChanged : 1;
111 #if !ASSERT_DISABLED
112     bool m_layoutDeltaXSaturated : 1;
113     bool m_layoutDeltaYSaturated : 1;
114 #endif
115
116     // The current line grid that we're snapping to and the offset of the start of the grid.
117     RenderBlockFlow* m_lineGrid { nullptr };
118
119     // FIXME: Distinguish between the layout clip rect and the paint clip rect which may be larger,
120     // e.g., because of composited scrolling.
121     LayoutRect m_clipRect;
122     
123     // x/y offset from layout root. Includes in-flow positioning and scroll offsets.
124     LayoutSize m_paintOffset;
125     // x/y offset from layout root. Does not include in-flow positioning or scroll offsets.
126     LayoutSize m_layoutOffset;
127     // Transient offset from the final position of the object
128     // used to ensure that repaints happen in the correct place.
129     // This is a total delta accumulated from the root. 
130     LayoutSize m_layoutDelta;
131
132     // The current page height for the pagination model that encloses us.
133     LayoutUnit m_pageLogicalHeight;
134     // The offset of the start of the first page in the nearest enclosing pagination model.
135     LayoutSize m_pageOffset;
136     LayoutSize m_lineGridOffset;
137     LayoutSize m_lineGridPaginationOrigin;
138
139     RenderFragmentedFlow* m_currentRenderFragmentedFlow { nullptr };
140 #ifndef NDEBUG
141     RenderElement* m_renderer { nullptr };
142 #endif
143 };
144
145 // Stack-based class to assist with LayoutState push/pop
146 class LayoutStateMaintainer {
147     WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer);
148 public:
149     // Constructor to push now.
150     explicit LayoutStateMaintainer(RenderBox&, LayoutSize offset, bool disableState = false, LayoutUnit pageHeight = 0, bool pageHeightChanged = false);
151     // Constructor to maybe push later.
152     explicit LayoutStateMaintainer(LayoutContext&);
153     ~LayoutStateMaintainer();
154
155     void push(RenderBox& root, LayoutSize offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false);
156     void pop();
157     bool didPush() const { return m_didCallPush; }
158
159 private:
160     LayoutContext& m_layoutContext;
161     bool m_paintOffsetCacheIsDisabled { false };
162     bool m_didCallPush { false };
163     bool m_didCallPop { false };
164     bool m_didPushLayoutState { false };
165 };
166
167 class SubtreeLayoutStateMaintainer {
168 public:
169     SubtreeLayoutStateMaintainer(RenderElement* subtreeLayoutRoot);
170     ~SubtreeLayoutStateMaintainer();
171
172 private:
173     RenderElement* m_subtreeLayoutRoot { nullptr };
174     bool m_didDisablePaintOffsetCache { false };
175 };
176
177 class LayoutStateDisabler {
178     WTF_MAKE_NONCOPYABLE(LayoutStateDisabler);
179 public:
180     LayoutStateDisabler(LayoutContext&);
181     ~LayoutStateDisabler();
182
183 private:
184     LayoutContext& m_layoutContext;
185 };
186
187 class PaginatedLayoutStateMaintainer {
188 public:
189     PaginatedLayoutStateMaintainer(RenderBlockFlow&);
190     ~PaginatedLayoutStateMaintainer();
191
192 private:
193     RenderBlockFlow& m_flow;
194     bool m_pushed { false };
195 };
196
197 } // namespace WebCore