[LFC] Adjust static position with containing block's content box top/left
[WebKit-https.git] / Source / WebCore / layout / displaytree / DisplayBox.h
index 3cdfb1c5d08fe1c3bf2112679170123efad17b9b..ba2d866a1a21be4b54acaf9ba64428c631838788 100644 (file)
 #include "LayoutPoint.h"
 #include "LayoutRect.h"
 #include "LayoutUnit.h"
+#include "RenderStyleConstants.h"
 #include <wtf/IsoMalloc.h>
 
 namespace WebCore {
 
+class RenderStyle;
+
 namespace Layout {
-class LayoutContext;
 class BlockFormattingContext;
+class FormattingContext;
+class LayoutContext;
 }
 
 namespace Display {
@@ -44,203 +48,263 @@ namespace Display {
 class Box {
     WTF_MAKE_ISO_ALLOCATED(Box);
 public:
-    friend class Layout::LayoutContext;
     friend class Layout::BlockFormattingContext;
+    friend class Layout::FormattingContext;
+    friend class Layout::LayoutContext;
 
-    ~Box();
+    class Rect {
+    public:
+        Rect() = default;
+        
+        LayoutUnit top() const;
+        LayoutUnit left() const;
+        LayoutPoint topLeft() const;
+
+        LayoutUnit bottom() const;
+        LayoutUnit right() const;        
+        LayoutPoint bottomRight() const;
+
+        LayoutUnit width() const;
+        LayoutUnit height() const;
+        LayoutSize size() const;
+
+        void setTop(LayoutUnit);
+        void setLeft(LayoutUnit);
+        void setTopLeft(const LayoutPoint&);
+        void setWidth(LayoutUnit);
+        void setHeight(LayoutUnit);
+        void setSize(const LayoutSize&);
+
+        void shiftLeftTo(LayoutUnit);
+        void shiftRightTo(LayoutUnit);
+        void shiftTopTo(LayoutUnit);
+        void shiftBottomTo(LayoutUnit);
+
+        void moveHorizontally(LayoutUnit);
+        void moveVertically(LayoutUnit);
+
+        void expand(LayoutUnit, LayoutUnit);
+
+        Rect clone() const;
+        operator LayoutRect() const;
+
+    private:
+#if !ASSERT_DISABLED
+        void invalidateTop() { m_hasValidTop = false; }
+        void invalidateLeft() { m_hasValidLeft = false; }
+        void invalidateWidth() { m_hasValidWidth = false; }
+        void invalidateHeight() { m_hasValidHeight = false; }
+        void invalidatePosition();
+
+        bool hasValidPosition() const { return m_hasValidTop && m_hasValidLeft; }
+        bool hasValidSize() const { return m_hasValidWidth && m_hasValidHeight; }
+        bool hasValidGeometry() const { return hasValidPosition() && hasValidSize(); }
+    
+        void setHasValidPosition();
+        void setHasValidSize();
+
+        bool m_hasValidTop { false };
+        bool m_hasValidLeft { false };
+        bool m_hasValidWidth { false };
+        bool m_hasValidHeight { false };
+#endif
+        LayoutRect m_rect;
+    };
 
-    LayoutRect rect() const;
+    ~Box();
 
-    LayoutUnit top() const;
-    LayoutUnit left() const;
-    LayoutUnit bottom() const;
-    LayoutUnit right() const;
+    LayoutUnit top() const { return m_topLeft.y(); }
+    LayoutUnit left() const { return m_topLeft.x(); }
+    LayoutUnit bottom() const { return top() + height(); }
+    LayoutUnit right() const { return left() + width(); }
 
-    LayoutPoint topLeft() const;
-    LayoutPoint bottomRight() const;
+    LayoutPoint topLeft() const { return m_topLeft; }
+    LayoutPoint bottomRight() const { return { right(), bottom() }; }
 
-    LayoutSize size() const;
-    LayoutUnit width() const;
-    LayoutUnit height() const;
+    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() }; }
 
     LayoutUnit marginTop() const;
     LayoutUnit marginLeft() const;
     LayoutUnit marginBottom() const;
     LayoutUnit marginRight() const;
 
-    LayoutRect marginBox() const;
-    LayoutRect borderBox() const;
-    LayoutRect paddingBox() const;
-    LayoutRect contentBox() const;
+    LayoutUnit borderTop() const;
+    LayoutUnit borderLeft() const;
+    LayoutUnit borderBottom() const;
+    LayoutUnit borderRight() const;
+
+    LayoutUnit paddingTop() const;
+    LayoutUnit paddingLeft() const;
+    LayoutUnit paddingBottom() const;
+    LayoutUnit paddingRight() const;
+
+    LayoutUnit contentBoxTop() const { return borderTop() + paddingTop(); }
+    LayoutUnit contentBoxLeft() const { return borderLeft() + paddingLeft(); }
+    LayoutUnit contentBoxHeight() const;
+    LayoutUnit contentBoxWidth() const;
+
+    Rect marginBox() const;
+    Rect borderBox() const;
+    Rect paddingBox() const;
+    Rect contentBox() const;
 
 private:
-    Box();
+    Box(const RenderStyle&);
+
+    struct Style {
+        Style(const RenderStyle&);
+
+        BoxSizing boxSizing { BoxSizing::ContentBox };
+    };
+
+    void setTopLeft(const LayoutPoint& topLeft) { m_topLeft = topLeft; }
+    void setTop(LayoutUnit top) { m_topLeft.setY(top); }
+    void setLeft(LayoutUnit left) { m_topLeft.setX(left); }
+    void moveHorizontally(LayoutUnit offset) { m_topLeft.move(offset, { }); }
+    void moveVertically(LayoutUnit offset) { m_topLeft.move({ }, offset); }
+
+    void setContentBoxHeight(LayoutUnit);
+    void setContentBoxWidth(LayoutUnit);
 
-    void setRect(const LayoutRect&);
-    void setTopLeft(const LayoutPoint&);
-    void setTop(LayoutUnit);
-    void setLeft(LayoutUnit);
-    void setSize(const LayoutSize&);
-    void setWidth(LayoutUnit);
-    void setHeight(LayoutUnit);
+    struct HorizontalEdges {
+        LayoutUnit left;
+        LayoutUnit right;
+    };
 
-    void setMargin(LayoutUnit marginTop, LayoutUnit marginLeft, LayoutUnit marginRight, LayoutUnit marginBottom);
-    void setBorder(LayoutUnit borderTop, LayoutUnit borderLeft, LayoutUnit borderRight, LayoutUnit borderBottom);
-    void setPadding(LayoutUnit paddingTop, LayoutUnit paddingLeft, LayoutUnit paddingRight, LayoutUnit paddingBottom);
+    struct VerticalEdges {
+        LayoutUnit top;
+        LayoutUnit bottom;
+    };
+
+    struct Edges {
+        HorizontalEdges horizontal;
+        VerticalEdges vertical;
+    };
+
+    void setHorizontalMargin(HorizontalEdges);
+    void setVerticalMargin(VerticalEdges);
+    void setBorder(Edges);
+    void setPadding(Edges);
 
 #if !ASSERT_DISABLED
-    void invalidateTop() { m_hasValidTop = false; }
-    void invalidateLeft() { m_hasValidLeft = false; }
-    void invalidateWidth() { m_hasValidWidth = false; }
-    void invalidateHeight() { m_hasValidHeight = false; }
-    void invalidatePosition();
-    void invalidateSize();
-    void invalidateMargin() { m_hasValidMargin = false; }
+    void invalidateMargin();
     void invalidateBorder() { m_hasValidBorder = false; }
     void invalidatePadding() { m_hasValidPadding = false; }
 
-    bool hasValidPosition() const { return m_hasValidTop && m_hasValidLeft; }
-    bool hasValidSize() const { return m_hasValidWidth && m_hasValidHeight; }
-    bool hasValidGeometry() const { return hasValidPosition() && hasValidSize(); }
-    
-    void setHasValidPosition();
-    void setHasValidSize();
-    void setHasValidGeometry();
-    
-    void setHasValidMargin();
-    void setHasValidBorder();
-    void setHasValidPadding();
-#endif
+    void setHasValidVerticalMargin() { m_hasValidVerticalMargin = true; }
+    void setHasValidHorizontalMargin() { m_hasValidHorizontalMargin = true; }
+
+    void setHasValidBorder() { m_hasValidBorder = true; }
+    void setHasValidPadding() { m_hasValidPadding = true; }
 
-    LayoutRect m_rect;
+    void setHasValidContentHeight() { m_hasValidContentHeight = true; }
+    void setHasValidContentWidth() { m_hasValidContentWidth = true; }
+#endif
 
-    LayoutUnit m_marginTop;
-    LayoutUnit m_marginLeft;
-    LayoutUnit m_marginBottom;
-    LayoutUnit m_marginRight;
+    const Style m_style;
 
-    LayoutUnit m_borderTop;
-    LayoutUnit m_borderLeft;
-    LayoutUnit m_borderBottom;
-    LayoutUnit m_borderRight;
+    LayoutPoint m_topLeft;
+    LayoutUnit m_contentWidth;
+    LayoutUnit m_contentHeight;
 
-    LayoutUnit m_paddingTop;
-    LayoutUnit m_paddingLeft;
-    LayoutUnit m_paddingBottom;
-    LayoutUnit m_paddingRight;
+    Edges m_margin;
+    Edges m_border;
+    Edges m_padding;
 
 #if !ASSERT_DISABLED
-    bool m_hasValidTop { false };
-    bool m_hasValidLeft { false };
-    bool m_hasValidWidth { false };
-    bool m_hasValidHeight { false };
-    bool m_hasValidMargin { false };
+    bool m_hasValidHorizontalMargin { false };
+    bool m_hasValidVerticalMargin { false };
     bool m_hasValidBorder { false };
     bool m_hasValidPadding { false };
+    bool m_hasValidContentHeight { false };
+    bool m_hasValidContentWidth { false };
 #endif
 };
 
 #if !ASSERT_DISABLED
-inline void Box::invalidatePosition()
+inline void Box::Rect::invalidatePosition()
 {
     invalidateTop();
     invalidateLeft();
 }
 
-inline void Box::invalidateSize()
-{
-    invalidateWidth();
-    invalidateHeight();
-}
-
-inline void Box::setHasValidPosition()
+inline void Box::Rect::setHasValidPosition()
 {
     m_hasValidTop = true;
     m_hasValidLeft = true;
 }
 
-inline void Box::setHasValidSize()
+inline void Box::Rect::setHasValidSize()
 {
     m_hasValidWidth = true;
     m_hasValidHeight = true;
 }
 
-inline void Box::setHasValidGeometry()
+inline void Box::invalidateMargin()
 {
-    setHasValidPosition();
-    setHasValidSize();
+    m_hasValidHorizontalMargin = false;
+    m_hasValidVerticalMargin = false;
 }
 #endif
 
-inline LayoutRect Box::rect() const
-{
-    ASSERT(hasValidGeometry());
-    return m_rect;
-}
-
-inline LayoutUnit Box::top() const
+inline LayoutUnit Box::Rect::top() const
 {
     ASSERT(m_hasValidTop);
     return m_rect.y();
 }
 
-inline LayoutUnit Box::left() const
+inline LayoutUnit Box::Rect::left() const
 {
     ASSERT(m_hasValidLeft);
     return m_rect.x();
 }
 
-inline LayoutUnit Box::bottom() const
+inline LayoutUnit Box::Rect::bottom() const
 {
     ASSERT(m_hasValidTop && m_hasValidHeight);
     return m_rect.maxY();
 }
 
-inline LayoutUnit Box::right() const
+inline LayoutUnit Box::Rect::right() const
 {
     ASSERT(m_hasValidLeft && m_hasValidWidth);
     return m_rect.maxX();
 }
 
-inline LayoutPoint Box::topLeft() const
+inline LayoutPoint Box::Rect::topLeft() const
 {
     ASSERT(hasValidPosition());
-    return m_rect.location();
+    return m_rect.minXMinYCorner();
 }
 
-inline LayoutPoint Box::bottomRight() const
+inline LayoutPoint Box::Rect::bottomRight() const
 {
     ASSERT(hasValidGeometry());
     return m_rect.maxXMaxYCorner();
 }
 
-inline LayoutSize Box::size() const
+inline LayoutSize Box::Rect::size() const
 {
     ASSERT(hasValidSize());
     return m_rect.size();
 }
 
-inline LayoutUnit Box::width() const
+inline LayoutUnit Box::Rect::width() const
 {
     ASSERT(m_hasValidWidth);
     return m_rect.width();
 }
 
-inline LayoutUnit Box::height() const
+inline LayoutUnit Box::Rect::height() const
 {
     ASSERT(m_hasValidHeight);
     return m_rect.height();
 }
 
-inline void Box::setRect(const LayoutRect& rect)
-{
-#if !ASSERT_DISABLED
-    setHasValidGeometry();
-#endif
-    m_rect = rect;
-}
-
-inline void Box::setTopLeft(const LayoutPoint& topLeft)
+inline void Box::Rect::setTopLeft(const LayoutPoint& topLeft)
 {
 #if !ASSERT_DISABLED
     setHasValidPosition();
@@ -248,7 +312,7 @@ inline void Box::setTopLeft(const LayoutPoint& topLeft)
     m_rect.setLocation(topLeft);
 }
 
-inline void Box::setTop(LayoutUnit top)
+inline void Box::Rect::setTop(LayoutUnit top)
 {
 #if !ASSERT_DISABLED
     m_hasValidTop = true;
@@ -256,7 +320,7 @@ inline void Box::setTop(LayoutUnit top)
     m_rect.setY(top);
 }
 
-inline void Box::setLeft(LayoutUnit left)
+inline void Box::Rect::setLeft(LayoutUnit left)
 {
 #if !ASSERT_DISABLED
     m_hasValidLeft = true;
@@ -264,7 +328,23 @@ inline void Box::setLeft(LayoutUnit left)
     m_rect.setX(left);
 }
 
-inline void Box::setSize(const LayoutSize& size)
+inline void Box::Rect::setWidth(LayoutUnit width)
+{
+#if !ASSERT_DISABLED
+    m_hasValidWidth = true;
+#endif
+    m_rect.setWidth(width);
+}
+
+inline void Box::Rect::setHeight(LayoutUnit height)
+{
+#if !ASSERT_DISABLED
+    m_hasValidHeight = true;
+#endif
+    m_rect.setHeight(height);
+}
+
+inline void Box::Rect::setSize(const LayoutSize& size)
 {
 #if !ASSERT_DISABLED
     setHasValidSize();
@@ -272,77 +352,197 @@ inline void Box::setSize(const LayoutSize& size)
     m_rect.setSize(size);
 }
 
-inline void Box::setWidth(LayoutUnit width)
+inline void Box::Rect::shiftLeftTo(LayoutUnit left)
+{
+    ASSERT(m_hasValidLeft);
+    m_rect.shiftXEdgeTo(left);
+}
+
+inline void Box::Rect::shiftRightTo(LayoutUnit right)
 {
+    ASSERT(m_hasValidLeft && m_hasValidWidth);
+    m_rect.shiftMaxXEdgeTo(right);
+}
+
+inline void Box::Rect::shiftTopTo(LayoutUnit top)
+{
+    ASSERT(m_hasValidTop);
+    m_rect.shiftYEdgeTo(top);
+}
+
+inline void Box::Rect::shiftBottomTo(LayoutUnit bottom)
+{
+    ASSERT(m_hasValidTop && m_hasValidHeight);
+    m_rect.shiftMaxYEdgeTo(bottom);
+}
+
+inline void Box::Rect::moveHorizontally(LayoutUnit offset)
+{
+    ASSERT(m_hasValidLeft);
+    m_rect.move(offset, { });
+}
+
+inline void Box::Rect::moveVertically(LayoutUnit offset)
+{
+    ASSERT(m_hasValidTop);
+    m_rect.move({ }, offset);
+}
+
+inline void Box::Rect::expand(LayoutUnit width, LayoutUnit height)
+{
+    ASSERT(hasValidGeometry());
+    m_rect.expand(width, height);
+}
+
+inline Box::Rect Box::Rect::clone() const
+{
+    Rect rect;
 #if !ASSERT_DISABLED
-    m_hasValidWidth = true;
+    rect.m_hasValidTop = m_hasValidTop;
+    rect.m_hasValidLeft = m_hasValidLeft;
+    rect.m_hasValidWidth = m_hasValidWidth;
+    rect.m_hasValidHeight  = m_hasValidHeight;
+#endif 
+    rect.m_rect = m_rect;
+    return rect;
+}
+
+inline Box::Rect::operator LayoutRect() const
+{
+    ASSERT(hasValidGeometry()); 
+    return m_rect;
+}
+
+inline void Box::setContentBoxHeight(LayoutUnit height)
+{ 
+#if !ASSERT_DISABLED
+    setHasValidContentHeight();
 #endif
-    m_rect.setWidth(width);
+    m_contentHeight = height;
 }
 
-inline void Box::setHeight(LayoutUnit height)
+inline void Box::setContentBoxWidth(LayoutUnit width)
+{ 
+#if !ASSERT_DISABLED
+    setHasValidContentWidth();
+#endif
+    m_contentWidth = width;
+}
+
+inline LayoutUnit Box::contentBoxHeight() const
+{
+    ASSERT(m_hasValidContentHeight);
+    return m_contentHeight;
+}
+
+inline LayoutUnit Box::contentBoxWidth() const
+{
+    ASSERT(m_hasValidContentWidth);
+    return m_contentWidth;
+}
+
+inline void Box::setHorizontalMargin(HorizontalEdges margin)
 {
 #if !ASSERT_DISABLED
-    m_hasValidHeight = true;
+    setHasValidHorizontalMargin();
 #endif
-    m_rect.setHeight(height);
+    m_margin.horizontal = margin;
 }
 
-inline void Box::setMargin(LayoutUnit marginTop, LayoutUnit marginLeft, LayoutUnit marginRight, LayoutUnit marginBottom)
+inline void Box::setVerticalMargin(VerticalEdges margin)
 {
 #if !ASSERT_DISABLED
-    void setHasValidMargin();
+    setHasValidVerticalMargin();
 #endif
-    m_marginTop = marginTop;
-    m_marginLeft = marginLeft;
-    m_marginBottom = marginBottom;
-    m_marginRight = marginRight;
+    m_margin.vertical = margin;
 }
 
-inline void Box::setBorder(LayoutUnit borderTop, LayoutUnit borderLeft, LayoutUnit borderRight, LayoutUnit borderBottom)
+inline void Box::setBorder(Edges border)
 {
 #if !ASSERT_DISABLED
-    void setHasValidBorder();
+    setHasValidBorder();
 #endif
-    m_borderTop = borderTop;
-    m_borderLeft = borderLeft;
-    m_borderBottom = borderBottom;
-    m_borderRight = borderRight;
+    m_border = border;
 }
 
-inline void Box::setPadding(LayoutUnit paddingTop, LayoutUnit paddingLeft, LayoutUnit paddingRight, LayoutUnit paddingBottom)
+inline void Box::setPadding(Edges padding)
 {
 #if !ASSERT_DISABLED
-    void setHasValidPadding();
+    setHasValidPadding();
 #endif
-    m_paddingTop = paddingTop;
-    m_paddingLeft = paddingLeft;
-    m_paddingBottom = paddingBottom;
-    m_paddingRight = paddingRight;
+    m_padding = padding;
 }
 
 inline LayoutUnit Box::marginTop() const
 {
-    ASSERT(m_hasValidMargin);
-    return m_marginTop;
+    ASSERT(m_hasValidVerticalMargin);
+    return m_margin.vertical.top;
 }
 
 inline LayoutUnit Box::marginLeft() const
 {
-    ASSERT(m_hasValidMargin);
-    return m_marginLeft;
+    ASSERT(m_hasValidHorizontalMargin);
+    return m_margin.horizontal.left;
 }
 
 inline LayoutUnit Box::marginBottom() const
 {
-    ASSERT(m_hasValidMargin);
-    return m_marginBottom;
+    ASSERT(m_hasValidVerticalMargin);
+    return m_margin.vertical.bottom;
 }
 
 inline LayoutUnit Box::marginRight() const
 {
-    ASSERT(m_hasValidMargin);
-    return m_marginRight;
+    ASSERT(m_hasValidHorizontalMargin);
+    return m_margin.horizontal.right;
+}
+
+inline LayoutUnit Box::paddingTop() const
+{
+    ASSERT(m_hasValidPadding);
+    return m_padding.vertical.top;
+}
+
+inline LayoutUnit Box::paddingLeft() const
+{
+    ASSERT(m_hasValidPadding);
+    return m_padding.horizontal.left;
+}
+
+inline LayoutUnit Box::paddingBottom() const
+{
+    ASSERT(m_hasValidPadding);
+    return m_padding.vertical.bottom;
+}
+
+inline LayoutUnit Box::paddingRight() const
+{
+    ASSERT(m_hasValidPadding);
+    return m_padding.horizontal.right;
+}
+
+inline LayoutUnit Box::borderTop() const
+{
+    ASSERT(m_hasValidBorder);
+    return m_border.vertical.top;
+}
+
+inline LayoutUnit Box::borderLeft() const
+{
+    ASSERT(m_hasValidBorder);
+    return m_border.horizontal.left;
+}
+
+inline LayoutUnit Box::borderBottom() const
+{
+    ASSERT(m_hasValidBorder);
+    return m_border.vertical.bottom;
+}
+
+inline LayoutUnit Box::borderRight() const
+{
+    ASSERT(m_hasValidBorder);
+    return m_border.horizontal.right;
 }
 
 }