[LFC] Add Rect interface to Display::Box
[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     class Rect {
56     public:
57         Rect() = default;
58         Rect(const LayoutPoint&, const LayoutSize&);
59         
60         LayoutUnit top() const;
61         LayoutUnit left() const;
62         LayoutPoint topLeft() const;
63
64         LayoutUnit bottom() const;
65         LayoutUnit right() const;        
66         LayoutPoint bottomRight() const;
67
68         LayoutUnit width() const;
69         LayoutUnit height() const;
70         LayoutSize size() const;
71
72         void setTop(LayoutUnit);
73         void setLeft(LayoutUnit);
74         void setTopLeft(const LayoutPoint&);
75         void setWidth(LayoutUnit);
76         void setHeight(LayoutUnit);
77
78         void shiftLeftTo(LayoutUnit);
79         void shiftRightTo(LayoutUnit);
80         void shiftTopTo(LayoutUnit);
81         void shiftBottomTo(LayoutUnit);
82
83         void expand(LayoutUnit, LayoutUnit);
84
85     private:
86 #if !ASSERT_DISABLED
87         void invalidateTop() { m_hasValidTop = false; }
88         void invalidateLeft() { m_hasValidLeft = false; }
89         void invalidateWidth() { m_hasValidWidth = false; }
90         void invalidateHeight() { m_hasValidHeight = false; }
91         void invalidatePosition();
92
93         bool hasValidPosition() const { return m_hasValidTop && m_hasValidLeft; }
94         bool hasValidSize() const { return m_hasValidWidth && m_hasValidHeight; }
95         bool hasValidGeometry() const { return hasValidPosition() && hasValidSize(); }
96     
97         void setHasValidPosition();
98
99         bool m_hasValidTop { false };
100         bool m_hasValidLeft { false };
101         bool m_hasValidWidth { false };
102         bool m_hasValidHeight { false };
103 #endif
104         LayoutRect m_rect;
105     };
106
107     ~Box();
108
109     Rect rect() const { return m_rect; }
110
111     LayoutUnit top() const { return m_rect.top(); }
112     LayoutUnit left() const { return m_rect.left(); }
113     LayoutUnit bottom() const { return m_rect.bottom(); }
114     LayoutUnit right() const { return m_rect.right(); }
115
116     LayoutPoint topLeft() const { return m_rect.topLeft(); }
117     LayoutPoint bottomRight() const { return m_rect.bottomRight(); }
118
119     LayoutSize size() const { return m_rect.size(); }
120     LayoutUnit width() const { return m_rect.width(); }
121     LayoutUnit height() const { return m_rect.height(); }
122
123     LayoutUnit marginTop() const;
124     LayoutUnit marginLeft() const;
125     LayoutUnit marginBottom() const;
126     LayoutUnit marginRight() const;
127
128     LayoutUnit borderTop() const;
129     LayoutUnit borderLeft() const;
130     LayoutUnit borderBottom() const;
131     LayoutUnit borderRight() const;
132
133     LayoutUnit paddingTop() const;
134     LayoutUnit paddingLeft() const;
135     LayoutUnit paddingBottom() const;
136     LayoutUnit paddingRight() const;
137
138     Rect marginBox() const;
139     Rect borderBox() const;
140     Rect paddingBox() const;
141     Rect contentBox() const;
142
143 private:
144     Box(const RenderStyle&);
145
146     struct Style {
147         Style(const RenderStyle&);
148
149         BoxSizing boxSizing { BoxSizing::ContentBox };
150     };
151
152     void setTopLeft(const LayoutPoint& topLeft) { m_rect.setTopLeft(topLeft); }
153     void setTop(LayoutUnit top) { m_rect.setTop(top); }
154     void setLeft(LayoutUnit left) { m_rect.setLeft(left); }
155     void setWidth(LayoutUnit width) { m_rect.setWidth(width); }
156     void setHeight(LayoutUnit height) { m_rect.setHeight(height); }
157
158     struct Edges {
159         Edges() = default;
160         Edges(LayoutUnit top, LayoutUnit left, LayoutUnit bottom, LayoutUnit right)
161             : top(top)
162             , left(left)
163             , bottom(bottom)
164             , right(right)
165             { }
166
167         LayoutUnit top;
168         LayoutUnit left;
169         LayoutUnit bottom;
170         LayoutUnit right;
171     };
172     void setMargin(Edges);
173     void setBorder(Edges);
174     void setPadding(Edges);
175
176 #if !ASSERT_DISABLED
177     void invalidateMargin() { m_hasValidMargin = false; }
178     void invalidateBorder() { m_hasValidBorder = false; }
179     void invalidatePadding() { m_hasValidPadding = false; }
180
181     void setHasValidMargin();
182     void setHasValidBorder();
183     void setHasValidPadding();
184 #endif
185
186     const Style m_style;
187
188     Rect m_rect;
189
190     Edges m_margin;
191     Edges m_border;
192     Edges m_padding;
193
194 #if !ASSERT_DISABLED
195     bool m_hasValidMargin { false };
196     bool m_hasValidBorder { false };
197     bool m_hasValidPadding { false };
198 #endif
199 };
200
201 #if !ASSERT_DISABLED
202 inline void Box::Rect::invalidatePosition()
203 {
204     invalidateTop();
205     invalidateLeft();
206 }
207
208 inline void Box::Rect::setHasValidPosition()
209 {
210     m_hasValidTop = true;
211     m_hasValidLeft = true;
212 }
213 #endif
214
215 inline Box::Rect::Rect(const LayoutPoint& topLeft, const LayoutSize& size)
216     : m_rect(topLeft, size)
217 {
218
219 }
220
221 inline LayoutUnit Box::Rect::top() const
222 {
223     ASSERT(m_hasValidTop);
224     return m_rect.y();
225 }
226
227 inline LayoutUnit Box::Rect::left() const
228 {
229     ASSERT(m_hasValidLeft);
230     return m_rect.x();
231 }
232
233 inline LayoutUnit Box::Rect::bottom() const
234 {
235     ASSERT(m_hasValidTop && m_hasValidHeight);
236     return m_rect.maxY();
237 }
238
239 inline LayoutUnit Box::Rect::right() const
240 {
241     ASSERT(m_hasValidLeft && m_hasValidWidth);
242     return m_rect.maxX();
243 }
244
245 inline LayoutPoint Box::Rect::topLeft() const
246 {
247     ASSERT(hasValidPosition());
248     return m_rect.minXMinYCorner();
249 }
250
251 inline LayoutPoint Box::Rect::bottomRight() const
252 {
253     ASSERT(hasValidGeometry());
254     return m_rect.maxXMaxYCorner();
255 }
256
257 inline LayoutSize Box::Rect::size() const
258 {
259     ASSERT(hasValidSize());
260     return m_rect.size();
261 }
262
263 inline LayoutUnit Box::Rect::width() const
264 {
265     ASSERT(m_hasValidWidth);
266     return m_rect.width();
267 }
268
269 inline LayoutUnit Box::Rect::height() const
270 {
271     ASSERT(m_hasValidHeight);
272     return m_rect.height();
273 }
274
275 inline void Box::Rect::setTopLeft(const LayoutPoint& topLeft)
276 {
277 #if !ASSERT_DISABLED
278     setHasValidPosition();
279 #endif
280     m_rect.setLocation(topLeft);
281 }
282
283 inline void Box::Rect::setTop(LayoutUnit top)
284 {
285 #if !ASSERT_DISABLED
286     m_hasValidTop = true;
287 #endif
288     m_rect.setY(top);
289 }
290
291 inline void Box::Rect::setLeft(LayoutUnit left)
292 {
293 #if !ASSERT_DISABLED
294     m_hasValidLeft = true;
295 #endif
296     m_rect.setX(left);
297 }
298
299 inline void Box::Rect::setWidth(LayoutUnit width)
300 {
301 #if !ASSERT_DISABLED
302     m_hasValidWidth = true;
303 #endif
304     ASSERT(m_hasValidLeft);
305     m_rect.setWidth(width);
306 }
307
308 inline void Box::Rect::setHeight(LayoutUnit height)
309 {
310 #if !ASSERT_DISABLED
311     m_hasValidHeight = true;
312 #endif
313     ASSERT(m_hasValidTop);
314     m_rect.setHeight(height);
315 }
316
317 inline void Box::Rect::shiftLeftTo(LayoutUnit left)
318 {
319     ASSERT(m_hasValidLeft);
320     m_rect.shiftXEdgeTo(left);
321 }
322
323 inline void Box::Rect::shiftRightTo(LayoutUnit right)
324 {
325     ASSERT(m_hasValidLeft && m_hasValidWidth);
326     m_rect.shiftMaxXEdgeTo(right);
327 }
328
329 inline void Box::Rect::shiftTopTo(LayoutUnit top)
330 {
331     ASSERT(m_hasValidTop);
332     m_rect.shiftYEdgeTo(top);
333 }
334
335 inline void Box::Rect::shiftBottomTo(LayoutUnit bottom)
336 {
337     ASSERT(m_hasValidTop && m_hasValidHeight);
338     m_rect.shiftMaxYEdgeTo(bottom);
339 }
340
341 inline void Box::Rect::expand(LayoutUnit width, LayoutUnit height)
342 {
343     ASSERT(hasValidGeometry());
344     m_rect.expand(width, height);
345 }
346
347 inline void Box::setMargin(Edges margin)
348 {
349 #if !ASSERT_DISABLED
350     void setHasValidMargin();
351 #endif
352     m_margin = margin;
353 }
354
355 inline void Box::setBorder(Edges border)
356 {
357 #if !ASSERT_DISABLED
358     void setHasValidBorder();
359 #endif
360     m_border = border;
361 }
362
363 inline void Box::setPadding(Edges padding)
364 {
365 #if !ASSERT_DISABLED
366     void setHasValidPadding();
367 #endif
368     m_padding = padding;
369 }
370
371 inline LayoutUnit Box::marginTop() const
372 {
373     ASSERT(m_hasValidMargin);
374     return m_margin.top;
375 }
376
377 inline LayoutUnit Box::marginLeft() const
378 {
379     ASSERT(m_hasValidMargin);
380     return m_margin.left;
381 }
382
383 inline LayoutUnit Box::marginBottom() const
384 {
385     ASSERT(m_hasValidMargin);
386     return m_margin.bottom;
387 }
388
389 inline LayoutUnit Box::marginRight() const
390 {
391     ASSERT(m_hasValidMargin);
392     return m_margin.right;
393 }
394
395 inline LayoutUnit Box::paddingTop() const
396 {
397     ASSERT(m_hasValidPadding);
398     return m_padding.top;
399 }
400
401 inline LayoutUnit Box::paddingLeft() const
402 {
403     ASSERT(m_hasValidPadding);
404     return m_padding.left;
405 }
406
407 inline LayoutUnit Box::paddingBottom() const
408 {
409     ASSERT(m_hasValidPadding);
410     return m_padding.bottom;
411 }
412
413 inline LayoutUnit Box::paddingRight() const
414 {
415     ASSERT(m_hasValidPadding);
416     return m_padding.right;
417 }
418
419 inline LayoutUnit Box::borderTop() const
420 {
421     ASSERT(m_hasValidBorder);
422     return m_border.top;
423 }
424
425 inline LayoutUnit Box::borderLeft() const
426 {
427     ASSERT(m_hasValidBorder);
428     return m_border.left;
429 }
430
431 inline LayoutUnit Box::borderBottom() const
432 {
433     ASSERT(m_hasValidBorder);
434     return m_border.bottom;
435 }
436
437 inline LayoutUnit Box::borderRight() const
438 {
439     ASSERT(m_hasValidBorder);
440     return m_border.right;
441 }
442
443 }
444 }
445 #endif