e56ec73fc16654580a68cf8566eecb851e2bd67a
[WebKit-https.git] / Source / WebCore / layout / displaytree / DisplayBox.h
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 #pragma once
27
28 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
29
30 #include "LayoutPoint.h"
31 #include "LayoutRect.h"
32 #include "LayoutUnit.h"
33 #include "RenderStyleConstants.h"
34 #include <wtf/IsoMalloc.h>
35
36 namespace WebCore {
37
38 class RenderStyle;
39
40 namespace Layout {
41 class BlockFormattingContext;
42 class FormattingContext;
43 class LayoutContext;
44 }
45
46 namespace Display {
47
48 class Box {
49     WTF_MAKE_ISO_ALLOCATED(Box);
50 public:
51     friend class Layout::BlockFormattingContext;
52     friend class Layout::FormattingContext;
53     friend class Layout::LayoutContext;
54
55     ~Box();
56
57     LayoutRect rect() const;
58
59     LayoutUnit top() const;
60     LayoutUnit left() const;
61     LayoutUnit bottom() const;
62     LayoutUnit right() const;
63
64     LayoutPoint topLeft() const;
65     LayoutPoint bottomRight() const;
66
67     LayoutSize size() const;
68     LayoutUnit width() const;
69     LayoutUnit height() const;
70
71     LayoutUnit marginTop() const;
72     LayoutUnit marginLeft() const;
73     LayoutUnit marginBottom() const;
74     LayoutUnit marginRight() const;
75
76     LayoutUnit borderTop() const;
77     LayoutUnit borderLeft() const;
78     LayoutUnit borderBottom() const;
79     LayoutUnit borderRight() const;
80
81     LayoutUnit paddingTop() const;
82     LayoutUnit paddingLeft() const;
83     LayoutUnit paddingBottom() const;
84     LayoutUnit paddingRight() const;
85
86     LayoutRect marginBox() const;
87     LayoutRect borderBox() const;
88     LayoutRect paddingBox() const;
89     LayoutRect contentBox() const;
90
91 private:
92     Box(const RenderStyle&);
93
94     struct Style {
95         Style(const RenderStyle&);
96
97         BoxSizing boxSizing { BoxSizing::ContentBox };
98     };
99
100     void setTopLeft(const LayoutPoint&);
101     void setTop(LayoutUnit);
102     void setLeft(LayoutUnit);
103     void setWidth(LayoutUnit);
104     void setHeight(LayoutUnit);
105
106     struct Edges {
107         Edges() = default;
108         Edges(LayoutUnit top, LayoutUnit left, LayoutUnit bottom, LayoutUnit right)
109             : top(top)
110             , left(left)
111             , bottom(bottom)
112             , right(right)
113             { }
114
115         LayoutUnit top;
116         LayoutUnit left;
117         LayoutUnit bottom;
118         LayoutUnit right;
119     };
120     void setMargin(Edges);
121     void setBorder(Edges);
122     void setPadding(Edges);
123
124 #if !ASSERT_DISABLED
125     void invalidateTop() { m_hasValidTop = false; }
126     void invalidateLeft() { m_hasValidLeft = false; }
127     void invalidateWidth() { m_hasValidWidth = false; }
128     void invalidateHeight() { m_hasValidHeight = false; }
129     void invalidatePosition();
130     void invalidateMargin() { m_hasValidMargin = false; }
131     void invalidateBorder() { m_hasValidBorder = false; }
132     void invalidatePadding() { m_hasValidPadding = false; }
133
134     bool hasValidPosition() const { return m_hasValidTop && m_hasValidLeft; }
135     bool hasValidSize() const { return m_hasValidWidth && m_hasValidHeight; }
136     bool hasValidGeometry() const { return hasValidPosition() && hasValidSize(); }
137     
138     void setHasValidPosition();
139     
140     void setHasValidMargin();
141     void setHasValidBorder();
142     void setHasValidPadding();
143 #endif
144
145     const Style m_style;
146
147     LayoutRect m_rect;
148
149     Edges m_margin;
150     Edges m_border;
151     Edges m_padding;
152
153 #if !ASSERT_DISABLED
154     bool m_hasValidTop { false };
155     bool m_hasValidLeft { false };
156     bool m_hasValidWidth { false };
157     bool m_hasValidHeight { false };
158     bool m_hasValidMargin { false };
159     bool m_hasValidBorder { false };
160     bool m_hasValidPadding { false };
161 #endif
162 };
163
164 #if !ASSERT_DISABLED
165 inline void Box::invalidatePosition()
166 {
167     invalidateTop();
168     invalidateLeft();
169 }
170
171 inline void Box::setHasValidPosition()
172 {
173     m_hasValidTop = true;
174     m_hasValidLeft = true;
175 }
176 #endif
177
178 inline LayoutRect Box::rect() const
179 {
180     ASSERT(hasValidGeometry());
181     return m_rect;
182 }
183
184 inline LayoutUnit Box::top() const
185 {
186     ASSERT(m_hasValidTop);
187     return m_rect.y();
188 }
189
190 inline LayoutUnit Box::left() const
191 {
192     ASSERT(m_hasValidLeft);
193     return m_rect.x();
194 }
195
196 inline LayoutUnit Box::bottom() const
197 {
198     ASSERT(m_hasValidTop && m_hasValidHeight);
199     return m_rect.maxY();
200 }
201
202 inline LayoutUnit Box::right() const
203 {
204     ASSERT(m_hasValidLeft && m_hasValidWidth);
205     return m_rect.maxX();
206 }
207
208 inline LayoutPoint Box::topLeft() const
209 {
210     ASSERT(hasValidPosition());
211     return m_rect.location();
212 }
213
214 inline LayoutPoint Box::bottomRight() const
215 {
216     ASSERT(hasValidGeometry());
217     return m_rect.maxXMaxYCorner();
218 }
219
220 inline LayoutSize Box::size() const
221 {
222     ASSERT(hasValidSize());
223     return m_rect.size();
224 }
225
226 inline LayoutUnit Box::width() const
227 {
228     ASSERT(m_hasValidWidth);
229     return m_rect.width();
230 }
231
232 inline LayoutUnit Box::height() const
233 {
234     ASSERT(m_hasValidHeight);
235     return m_rect.height();
236 }
237
238 inline void Box::setTopLeft(const LayoutPoint& topLeft)
239 {
240 #if !ASSERT_DISABLED
241     setHasValidPosition();
242 #endif
243     m_rect.setLocation(topLeft);
244 }
245
246 inline void Box::setTop(LayoutUnit top)
247 {
248 #if !ASSERT_DISABLED
249     m_hasValidTop = true;
250 #endif
251     m_rect.setY(top);
252 }
253
254 inline void Box::setLeft(LayoutUnit left)
255 {
256 #if !ASSERT_DISABLED
257     m_hasValidLeft = true;
258 #endif
259     m_rect.setX(left);
260 }
261
262 inline void Box::setWidth(LayoutUnit width)
263 {
264 #if !ASSERT_DISABLED
265     m_hasValidWidth = true;
266 #endif
267     ASSERT(m_hasValidLeft);
268     m_rect.setWidth(width);
269 }
270
271 inline void Box::setHeight(LayoutUnit height)
272 {
273 #if !ASSERT_DISABLED
274     m_hasValidHeight = true;
275 #endif
276     ASSERT(m_hasValidTop);
277     m_rect.setHeight(height);
278 }
279
280 inline void Box::setMargin(Edges margin)
281 {
282 #if !ASSERT_DISABLED
283     void setHasValidMargin();
284 #endif
285     m_margin = margin;
286 }
287
288 inline void Box::setBorder(Edges border)
289 {
290 #if !ASSERT_DISABLED
291     void setHasValidBorder();
292 #endif
293     m_border = border;
294 }
295
296 inline void Box::setPadding(Edges padding)
297 {
298 #if !ASSERT_DISABLED
299     void setHasValidPadding();
300 #endif
301     m_padding = padding;
302 }
303
304 inline LayoutUnit Box::marginTop() const
305 {
306     ASSERT(m_hasValidMargin);
307     return m_margin.top;
308 }
309
310 inline LayoutUnit Box::marginLeft() const
311 {
312     ASSERT(m_hasValidMargin);
313     return m_margin.left;
314 }
315
316 inline LayoutUnit Box::marginBottom() const
317 {
318     ASSERT(m_hasValidMargin);
319     return m_margin.bottom;
320 }
321
322 inline LayoutUnit Box::marginRight() const
323 {
324     ASSERT(m_hasValidMargin);
325     return m_margin.right;
326 }
327
328 inline LayoutUnit Box::paddingTop() const
329 {
330     ASSERT(m_hasValidPadding);
331     return m_padding.top;
332 }
333
334 inline LayoutUnit Box::paddingLeft() const
335 {
336     ASSERT(m_hasValidPadding);
337     return m_padding.left;
338 }
339
340 inline LayoutUnit Box::paddingBottom() const
341 {
342     ASSERT(m_hasValidPadding);
343     return m_padding.bottom;
344 }
345
346 inline LayoutUnit Box::paddingRight() const
347 {
348     ASSERT(m_hasValidPadding);
349     return m_padding.right;
350 }
351
352 inline LayoutUnit Box::borderTop() const
353 {
354     ASSERT(m_hasValidBorder);
355     return m_border.top;
356 }
357
358 inline LayoutUnit Box::borderLeft() const
359 {
360     ASSERT(m_hasValidBorder);
361     return m_border.left;
362 }
363
364 inline LayoutUnit Box::borderBottom() const
365 {
366     ASSERT(m_hasValidBorder);
367     return m_border.bottom;
368 }
369
370 inline LayoutUnit Box::borderRight() const
371 {
372     ASSERT(m_hasValidBorder);
373     return m_border.right;
374 }
375
376 }
377 }
378 #endif