Diff
Modified: trunk/Source/WebCore/ChangeLog (234422 => 234423)
--- trunk/Source/WebCore/ChangeLog 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/ChangeLog 2018-07-31 15:02:18 UTC (rev 234423)
@@ -1,3 +1,47 @@
+2018-07-31 Zalan Bujtas <[email protected]>
+
+ [LFC][Floating] Add basic left/right floating positioning.
+ https://bugs.webkit.org/show_bug.cgi?id=188148
+
+ Reviewed by Antti Koivisto.
+
+ This patch implements simple floating positioning.
+ (Floatings with different containing blocks do not work yet.)
+
+ * layout/FloatingContext.cpp:
+ (WebCore::Layout::FloatingPair::isEmpty const):
+ (WebCore::Layout::Iterator::current const):
+ (WebCore::Layout::Iterator::verticalPosition const):
+ (WebCore::Layout::FloatingContext::FloatingContext):
+ (WebCore::Layout::FloatingContext::computePosition const):
+ (WebCore::Layout::FloatingContext::floatingPosition const):
+ (WebCore::Layout::FloatingContext::initialVerticalPosition const):
+ (WebCore::Layout::FloatingContext::alignWithContainingBlock const):
+ (WebCore::Layout::FloatingContext::alignWithFloatings const):
+ (WebCore::Layout::floatingDisplayBox):
+ (WebCore::Layout::FloatingPair::FloatingPair):
+ (WebCore::Layout::FloatingPair::left const):
+ (WebCore::Layout::FloatingPair::right const):
+ (WebCore::Layout::FloatingPair::intersects const):
+ (WebCore::Layout::Iterator::Iterator):
+ (WebCore::Layout::Iterator::operator++):
+ (WebCore::Layout::Iterator::set):
+ (WebCore::Layout::FloatingContext::computePosition): Deleted.
+ * layout/FloatingContext.h:
+ * layout/FloatingState.cpp:
+ (WebCore::Layout::FloatingState::append):
+ * layout/FloatingState.h:
+ (WebCore::Layout::FloatingState::floatings const):
+ (WebCore::Layout::FloatingState::last const):
+ * layout/blockformatting/BlockFormattingContext.cpp:
+ (WebCore::Layout::BlockFormattingContext::layout const):
+ (WebCore::Layout::BlockFormattingContext::layoutFormattingContextRoot const):
+ * layout/displaytree/DisplayBox.cpp:
+ (WebCore::Display::Box::Rect::Rect):
+ * layout/displaytree/DisplayBox.h:
+ (WebCore::Display::Box::Rect::intersects const):
+ (WebCore::Display::Box::rect const):
+
2018-07-31 Rob Buis <[email protected]>
Remove ResourceResponse::cacheBodyKey API
Modified: trunk/Source/WebCore/layout/FloatingContext.cpp (234422 => 234423)
--- trunk/Source/WebCore/layout/FloatingContext.cpp 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/layout/FloatingContext.cpp 2018-07-31 15:02:18 UTC (rev 234423)
@@ -28,6 +28,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "DisplayBox.h"
#include "LayoutBox.h"
#include "LayoutContainer.h"
#include "LayoutContext.h"
@@ -38,31 +39,337 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(FloatingContext);
-FloatingContext::FloatingContext(FloatingState& floatingState)
- : m_floatingState(floatingState)
+// Finding the top/left position for a new floating(F)
+// ____ ____ _____ _______
+// | || L2 || | <-----1---->| |
+// | ||____|| L3 | | R1 |
+// | L1 | |_____| | |
+// |____| <-------------2--------->| |
+// | |
+// |_______|
+//
+// 1. Compute the initial vertical position for (F) -> (1)
+// 2. Find the corresponding floating pair (L3-R1)
+// 3. Align (F) horizontally with (L3-R1) depending whether (F) is left/right positioned
+// 4. Intersect (F) with (L3-R1)
+// 5. If (F) does not fit, find the next floating pair (L1-R1)
+// 6. Repeat until either (F) fits/no more floatings.
+
+class Iterator;
+
+class FloatingPair {
+public:
+ FloatingPair(const LayoutContext&, const FloatingState&);
+
+ bool isEmpty() const { return !m_leftIndex && !m_rightIndex; }
+ const Display::Box* left() const;
+ const Display::Box* right() const;
+ bool intersects(const Display::Box::Rect&) const;
+ LayoutUnit verticalPosition() const { return m_verticalPosition; }
+ bool operator==(const FloatingPair&) const;
+
+private:
+ friend class Iterator;
+ const LayoutContext& m_layoutContext;
+ const FloatingState& m_floatingState;
+
+ std::optional<unsigned> m_leftIndex;
+ std::optional<unsigned> m_rightIndex;
+ LayoutUnit m_verticalPosition;
+};
+
+class Iterator {
+public:
+ Iterator(const LayoutContext&, const FloatingState&, std::optional<LayoutUnit> verticalPosition);
+
+ const FloatingPair& operator*() const { return m_current; }
+ Iterator& operator++();
+ bool operator==(const Iterator&) const;
+ bool operator!=(const Iterator&) const;
+
+private:
+ void set(LayoutUnit verticalPosition);
+
+ const LayoutContext& m_layoutContext;
+ const FloatingState& m_floatingState;
+ FloatingPair m_current;
+};
+
+static Iterator begin(const LayoutContext& layoutContext, const FloatingState& floatingState, LayoutUnit initialVerticalPosition)
{
+ // Start with the inner-most floating pair for the initial vertical position.
+ return Iterator(layoutContext, floatingState, initialVerticalPosition);
}
-Position FloatingContext::computePosition(const Box& layoutBox)
+static Iterator end(const LayoutContext& layoutContext, const FloatingState& floatingState)
{
+ return Iterator(layoutContext, floatingState, std::nullopt);
+}
+
+FloatingContext::FloatingContext(const Container& formattingContextRoot, FloatingState& floatingState)
+ : m_formattingContextRoot(formattingContextRoot)
+ , m_floatingState(floatingState)
+{
+ ASSERT(m_formattingContextRoot.establishesFormattingContext());
+}
+
+Position FloatingContext::computePosition(const Box& layoutBox) const
+{
+ ASSERT(layoutBox.isFloatingPositioned());
+
+ // 1. No floating box on the context yet -> align it with the containing block's left/right edge.
+ if (m_floatingState.isEmpty())
+ return { alignWithContainingBlock(layoutBox), layoutContext().displayBoxForLayoutBox(layoutBox)->top() };
+
+ // 2. Find the top most position where the floating fits.
+ return floatingPosition(layoutBox);
+}
+
+Position FloatingContext::floatingPosition(const Box& layoutBox) const
+{
+ auto initialVerticalPosition = this->initialVerticalPosition(layoutBox);
+ auto boxSize = layoutContext().displayBoxForLayoutBox(layoutBox)->marginBox().size();
+
+ auto end = Layout::end(layoutContext(), m_floatingState);
+ auto top = initialVerticalPosition;
+ for (auto iterator = begin(layoutContext(), m_floatingState, initialVerticalPosition); iterator != end; ++iterator) {
+ ASSERT(!(*iterator).isEmpty());
+
+ auto floatings = *iterator;
+ top = floatings.verticalPosition();
+
+ // Move the box horizontally so that it aligns with the current floating pair.
+ auto left = alignWithFloatings(floatings, layoutBox);
+ // Check if the box fits at this vertical position.
+ if (!floatings.intersects({ top, left, boxSize.width(), boxSize.height() }))
+ return { left, top };
+
+ // Move to the next floating pair.
+ }
+
+ // Passed all the floatings and still does not fit?
+ return { alignWithContainingBlock(layoutBox), top };
+}
+
+LayoutUnit FloatingContext::initialVerticalPosition(const Box& layoutBox) const
+{
+ // Incoming floating cannot be placed higher than existing floatings.
+ // Take the static position (where the box would go if it wasn't floating) and adjust it with the last floating.
+ auto& displayBox = *layoutContext().displayBoxForLayoutBox(layoutBox);
+
+ if (auto lastFloating = m_floatingState.last())
+ return std::max(displayBox.top(), layoutContext().displayBoxForLayoutBox(*lastFloating)->top());
+
+ return displayBox.top();
+}
+
+LayoutUnit FloatingContext::alignWithContainingBlock(const Box& layoutBox) const
+{
+ // If there is no floating to align with, push the box to the left/right edge of its containing block's content box.
+ // (Either there's no floatings at all or this box does not fit at any vertical positions where the floatings are.)
auto& layoutContext = m_floatingState.layoutContext();
- // 1. No floating box on the context yet -> align it with the containing block's left/right edge.
- if (m_floatingState.isEmpty()) {
- // Push the box to the left/right edge.
- auto* containingBlock = layoutBox.containingBlock();
- auto* displayBox = layoutContext.displayBoxForLayoutBox(*containingBlock);
+ auto* containingBlock = layoutBox.containingBlock();
+ ASSERT(containingBlock == &m_formattingContextRoot || containingBlock->isDescendantOf(m_formattingContextRoot));
- if (layoutBox.isLeftFloatingPositioned())
- return { displayBox->contentBoxLeft(), displayBox->contentBoxTop() };
+ auto* containgBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*containingBlock);
- auto boxWidth = layoutContext.displayBoxForLayoutBox(layoutBox)->width();
- return { displayBox->contentBoxRight() - boxWidth, displayBox->contentBoxTop() };
+ if (layoutBox.isLeftFloatingPositioned())
+ return containgBlockDisplayBox->contentBoxLeft();
+
+ auto boxWidth = layoutContext.displayBoxForLayoutBox(layoutBox)->marginBox().width();
+ return containgBlockDisplayBox->contentBoxRight() - boxWidth;
+}
+
+LayoutUnit FloatingContext::alignWithFloatings(const FloatingPair& floatingPair, const Box& layoutBox) const
+{
+ // Compute the horizontal position for the new floating by taking both the contining block and the current left/right floatings into account.
+ auto& containingBlock = *layoutContext().displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto containingBlockContentLeft = containingBlock.contentBoxLeft();
+ auto containingBlockContentRight = containingBlock.contentBoxRight();
+ auto marginBoxWidth = layoutContext().displayBoxForLayoutBox(layoutBox)->marginBox().width();
+
+ if (floatingPair.isEmpty()) {
+ ASSERT_NOT_REACHED();
+ return layoutBox.isLeftFloatingPositioned() ? containingBlockContentLeft : containingBlockContentRight - marginBoxWidth;
}
- ASSERT_NOT_IMPLEMENTED_YET();
- return { };
+ if (layoutBox.isLeftFloatingPositioned()) {
+ if (auto* leftDisplayBox = floatingPair.left())
+ return std::min(std::max(containingBlockContentLeft, leftDisplayBox->right()), containingBlockContentRight - marginBoxWidth);
+
+ return containingBlockContentLeft;
+ }
+
+ ASSERT(layoutBox.isRightFloatingPositioned());
+
+ if (auto* rightDisplayBox = floatingPair.right())
+ return std::max(std::min(containingBlockContentRight, rightDisplayBox->left()) - marginBoxWidth, containingBlockContentLeft);
+
+ return containingBlockContentRight - marginBoxWidth;
}
+static const Display::Box* floatingDisplayBox(unsigned index, const FloatingState::FloatingList& floatings, const LayoutContext& layoutContext)
+{
+ RELEASE_ASSERT(index < floatings.size());
+ return layoutContext.displayBoxForLayoutBox(*floatings[index]);
}
+
+FloatingPair::FloatingPair(const LayoutContext& layoutContext, const FloatingState& floatingState)
+ : m_layoutContext(layoutContext)
+ , m_floatingState(floatingState)
+{
}
+
+const Display::Box* FloatingPair::left() const
+{
+ if (!m_leftIndex)
+ return nullptr;
+
+ return floatingDisplayBox(*m_leftIndex, m_floatingState.floatings().left, m_layoutContext);
+}
+
+const Display::Box* FloatingPair::right() const
+{
+ if (!m_rightIndex)
+ return nullptr;
+
+ return floatingDisplayBox(*m_rightIndex, m_floatingState.floatings().right, m_layoutContext);
+}
+
+bool FloatingPair::intersects(const Display::Box::Rect& rect) const
+{
+ auto intersects = [&](const Display::Box* floating, const Display::Box::Rect& rect) {
+ if (!floating)
+ return false;
+ // FIXME: use margin box here.
+ return floating->rect().intersects(rect);
+ };
+
+ if (!m_leftIndex && !m_rightIndex) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ if (intersects(left(), rect))
+ return true;
+
+ if (intersects(right(), rect))
+ return true;
+
+ return false;
+}
+
+bool FloatingPair::operator ==(const FloatingPair& other) const
+{
+ return m_leftIndex == other.m_leftIndex && m_rightIndex == other.m_rightIndex;
+}
+
+Iterator::Iterator(const LayoutContext& layoutContext, const FloatingState& floatingState, std::optional<LayoutUnit> verticalPosition)
+ : m_layoutContext(layoutContext)
+ , m_floatingState(floatingState)
+ , m_current(layoutContext, floatingState)
+{
+ if (verticalPosition)
+ set(*verticalPosition);
+}
+
+Iterator& Iterator::operator++()
+{
+ if (m_current.isEmpty()) {
+ ASSERT_NOT_REACHED();
+ return *this;
+ }
+
+ auto previousFloatingIndex = [&](const FloatingState::FloatingList& floatings, unsigned index) -> std::optional<unsigned> {
+
+ RELEASE_ASSERT(index < floatings.size());
+
+ if (!index)
+ return { };
+
+ auto currentBottom = floatingDisplayBox(index--, floatings, m_layoutContext)->bottom();
+ while (true) {
+ if (floatingDisplayBox(index, floatings, m_layoutContext)->bottom() > currentBottom)
+ return index;
+ if (!index--)
+ return { };
+ }
+
+ ASSERT_NOT_REACHED();
+ return { };
+ };
+
+ // 1. Take the current floating from left and right and check which one's bottom edge is positioned higher (they could be on the same vertical position too).
+ // The current floatings from left and right are considered the inner-most pair for the current vertical position.
+ // 2. Move away from inner-most pair by picking one of the previous floatings in the list(#1)
+ // Ensure that the new floating's bottom edge is positioned lower than the current one -which essentially means skipping in-between floats that are positioned higher).
+ // 3. Reset the vertical position and align it with the new left-right pair. These floatings are now the inner-most boxes for the current vertical position.
+ // As the result we have more horizontal space on the current vertical position.
+ auto leftBottom = m_current.left() ? std::optional<LayoutUnit>(m_current.left()->bottom()) : std::nullopt;
+ auto rightBottom = m_current.right() ? std::optional<LayoutUnit>(m_current.right()->bottom()) : std::nullopt;
+
+ auto updateLeft = (leftBottom == rightBottom) || (!rightBottom || (leftBottom && leftBottom < rightBottom));
+ auto updateRight = (leftBottom == rightBottom) || (!leftBottom || (rightBottom && leftBottom > rightBottom));
+
+ if (updateLeft) {
+ ASSERT(m_current.m_leftIndex);
+ m_current.m_verticalPosition = *leftBottom;
+ m_current.m_leftIndex = previousFloatingIndex(m_floatingState.floatings().left, *m_current.m_leftIndex);
+ }
+
+ if (updateRight) {
+ ASSERT(m_current.m_rightIndex);
+ m_current.m_verticalPosition = *rightBottom;
+ m_current.m_rightIndex = previousFloatingIndex(m_floatingState.floatings().right, *m_current.m_rightIndex);
+ }
+
+ return *this;
+}
+
+void Iterator::set(LayoutUnit verticalPosition)
+{
+ // Move the iterator to the initial vertical position by starting at the inner-most floating pair (last floats on left/right).
+ // 1. Check if the inner-most pair covers the vertical position.
+ // 2. Move outwards from the inner-most pair until the vertical postion intersects.
+ // (Note that verticalPosition has already been adjusted with the top of the last float.)
+
+ m_current.m_verticalPosition = verticalPosition;
+ // No floatings at all?
+ if (m_floatingState.isEmpty()) {
+ ASSERT_NOT_REACHED();
+
+ m_current.m_leftIndex = { };
+ m_current.m_rightIndex = { };
+ return;
+ }
+
+ auto findFloatingBelow = [&](const FloatingState::FloatingList& list) -> std::optional<unsigned> {
+
+ auto index = list.size();
+ while (index) {
+ auto bottom = floatingDisplayBox(--index, list, m_layoutContext)->bottom();
+ // Is this floating intrusive on this position?
+ if (bottom > verticalPosition)
+ return index;
+ }
+ return { };
+ };
+
+ auto& floatings = m_floatingState.floatings();
+ m_current.m_leftIndex = findFloatingBelow(floatings.left);
+ m_current.m_rightIndex = findFloatingBelow(floatings.right);
+}
+
+bool Iterator::operator==(const Iterator& other) const
+{
+ return m_current == other.m_current;
+}
+
+bool Iterator::operator!=(const Iterator& other) const
+{
+ return !(*this == other);
+}
+
+}
+}
#endif
Modified: trunk/Source/WebCore/layout/FloatingContext.h (234422 => 234423)
--- trunk/Source/WebCore/layout/FloatingContext.h 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/layout/FloatingContext.h 2018-07-31 15:02:18 UTC (rev 234423)
@@ -33,13 +33,11 @@
namespace WebCore {
-namespace Display {
-class Box;
-}
-
namespace Layout {
class Box;
+class Container;
+class FloatingPair;
class LayoutContext;
// FloatingContext is responsible for adjusting the position of a box in the current formatting context
@@ -47,15 +45,22 @@
class FloatingContext {
WTF_MAKE_ISO_ALLOCATED(FloatingContext);
public:
- FloatingContext(FloatingState&);
+ FloatingContext(const Container& formattingContextRoot, FloatingState&);
FloatingState& floatingState() const { return m_floatingState; }
- Position computePosition(const Box&);
+ Position computePosition(const Box&) const;
private:
LayoutContext& layoutContext() const { return m_floatingState.layoutContext(); }
+ Position floatingPosition(const Box&) const;
+
+ LayoutUnit initialVerticalPosition(const Box&) const;
+ LayoutUnit alignWithContainingBlock(const Box&) const;
+ LayoutUnit alignWithFloatings(const FloatingPair&, const Box&) const;
+
+ const Container& m_formattingContextRoot;
FloatingState& m_floatingState;
};
Modified: trunk/Source/WebCore/layout/FloatingState.cpp (234422 => 234423)
--- trunk/Source/WebCore/layout/FloatingState.cpp 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/layout/FloatingState.cpp 2018-07-31 15:02:18 UTC (rev 234423)
@@ -46,14 +46,15 @@
{
// Floating state should hold boxes with computed position/size.
ASSERT(m_layoutContext.displayBoxForLayoutBox(layoutBox));
+ m_last = makeWeakPtr(const_cast<Box&>(layoutBox));
if (layoutBox.isLeftFloatingPositioned()) {
- m_leftFloatings.append(makeWeakPtr(const_cast<Box&>(layoutBox)));
+ m_leftFloatings.append(m_last);
return;
}
if (layoutBox.isRightFloatingPositioned()) {
- m_rightFloatings.append(makeWeakPtr(const_cast<Box&>(layoutBox)));
+ m_rightFloatings.append(m_last);
return;
}
Modified: trunk/Source/WebCore/layout/FloatingState.h (234422 => 234423)
--- trunk/Source/WebCore/layout/FloatingState.h 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/layout/FloatingState.h 2018-07-31 15:02:18 UTC (rev 234423)
@@ -49,6 +49,14 @@
bool isEmpty() const { return m_leftFloatings.isEmpty() && m_rightFloatings.isEmpty(); }
+ using FloatingList = Vector<WeakPtr<Box>>;
+ struct Floatings {
+ const FloatingList& left;
+ const FloatingList& right;
+ };
+ const Floatings floatings() const { return { m_leftFloatings, m_rightFloatings }; }
+ const Box* last() const { return m_last.get(); }
+
private:
friend class FloatingContext;
FloatingState(LayoutContext&);
@@ -57,9 +65,9 @@
LayoutContext& m_layoutContext;
- using FloatingList = Vector<WeakPtr<Box>>;
FloatingList m_leftFloatings;
FloatingList m_rightFloatings;
+ WeakPtr<Box> m_last;
};
}
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (234422 => 234423)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2018-07-31 15:02:18 UTC (rev 234423)
@@ -62,7 +62,7 @@
auto& formattingRoot = downcast<Container>(root());
LayoutQueue layoutQueue;
- FloatingContext floatingContext(formattingState.floatingState());
+ FloatingContext floatingContext(formattingRoot, formattingState.floatingState());
// This is a post-order tree traversal layout.
// The root container layout is done in the formatting context it lives in, not that one it creates, so let's start with the first child.
if (auto* firstChild = formattingRoot.firstInFlowOrFloatingChild())
@@ -94,8 +94,6 @@
computeStaticPosition(layoutContext, layoutBox, displayBox);
computeBorderAndPadding(layoutContext, layoutBox, displayBox);
computeWidthAndMargin(layoutContext, layoutBox, displayBox);
- if (layoutBox.isFloatingPositioned())
- computeFloatingPosition(floatingContext, layoutBox, displayBox);
if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowOrFloatingChild())
break;
auto& firstChild = *downcast<Container>(layoutBox).firstInFlowOrFloatingChild();
@@ -138,8 +136,6 @@
computeStaticPosition(layoutContext, layoutBox, displayBox);
computeBorderAndPadding(layoutContext, layoutBox, displayBox);
computeWidthAndMargin(layoutContext, layoutBox, displayBox);
- if (layoutBox.isFloatingPositioned())
- computeFloatingPosition(floatingContext, layoutBox, displayBox);
// Swich over to the new formatting context (the one that the root creates).
auto formattingContext = layoutContext.formattingContext(layoutBox);
@@ -148,6 +144,8 @@
// Come back and finalize the root's geometry.
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Height][Margin] -> for layoutBox(" << &layoutBox << ")");
computeHeightAndMargin(layoutContext, layoutBox, displayBox);
+ if (layoutBox.isFloatingPositioned())
+ computeFloatingPosition(floatingContext, layoutBox, displayBox);
// Now that we computed the root's height, we can go back and layout the out-of-flow descedants (if any).
formattingContext->layoutOutOfFlowDescendants(layoutContext, layoutBox);
}
Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp (234422 => 234423)
--- trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp 2018-07-31 15:02:18 UTC (rev 234423)
@@ -36,6 +36,17 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(Box);
+Box::Rect::Rect(LayoutUnit top, LayoutUnit left, LayoutUnit width, LayoutUnit height)
+ : m_rect(left, top, width, height)
+{
+#if !ASSERT_DISABLED
+ m_hasValidTop = true;
+ m_hasValidLeft = true;
+ m_hasValidWidth = true;
+ m_hasValidHeight = true;
+#endif
+}
+
Box::Box(const RenderStyle& style)
: m_style(style)
{
Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.h (234422 => 234423)
--- trunk/Source/WebCore/layout/displaytree/DisplayBox.h 2018-07-31 12:01:48 UTC (rev 234422)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.h 2018-07-31 15:02:18 UTC (rev 234423)
@@ -53,6 +53,7 @@
class Rect {
public:
Rect() = default;
+ Rect(LayoutUnit top, LayoutUnit left, LayoutUnit width, LayoutUnit height);
LayoutUnit top() const;
LayoutUnit left() const;
@@ -82,6 +83,7 @@
void moveVertically(LayoutUnit);
void expand(LayoutUnit, LayoutUnit);
+ bool intersects(const Rect& rect) const { return m_rect.intersects(rect); }
Rect clone() const;
operator LayoutRect() const;
@@ -122,7 +124,7 @@
LayoutSize size() const { return { width(), height() }; }
LayoutUnit width() const { return borderLeft() + paddingLeft() + contentBoxWidth() + paddingRight() + borderRight(); }
LayoutUnit height() const { return borderTop() + paddingTop() + contentBoxHeight() + paddingBottom() + borderBottom(); }
- LayoutRect rect() const { return { left(), top(), width(), height() }; }
+ Rect rect() const { return { top(), left(), width(), height() }; }
LayoutUnit marginTop() const;
LayoutUnit marginLeft() const;