1/* 2 * Copyright (C) 2012 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#ifndef ScrollingConstraints_h 27#define ScrollingConstraints_h 28 29#include "FloatRect.h" 30 31namespace WebCore { 32 33// ViewportConstraints classes encapsulate data and logic required to reposition elements whose layout 34// depends on the viewport rect (positions fixed and sticky), when scrolling and zooming. 35class ViewportConstraints { 36public: 37 enum ConstraintType { 38 FixedPositionConstraint, 39 StickyPositionConstraint 40 }; 41 42 enum AnchorEdgeFlags { 43 AnchorEdgeLeft = 1 << 0, 44 AnchorEdgeRight = 1 << 1, 45 AnchorEdgeTop = 1 << 2, 46 AnchorEdgeBottom = 1 << 3 47 }; 48 typedef unsigned AnchorEdges; 49 50 ViewportConstraints(const ViewportConstraints& other) 51 : m_alignmentOffset(other.m_alignmentOffset) 52 , m_anchorEdges(other.m_anchorEdges) 53 { } 54 55 virtual ~ViewportConstraints() { } 56 57 virtual ConstraintType constraintType() const = 0; 58 59 AnchorEdges anchorEdges() const { return m_anchorEdges; } 60 bool hasAnchorEdge(AnchorEdgeFlags flag) const { return m_anchorEdges & flag; } 61 void addAnchorEdge(AnchorEdgeFlags edgeFlag) { m_anchorEdges |= edgeFlag; } 62 void setAnchorEdges(AnchorEdges edges) { m_anchorEdges = edges; } 63 64 FloatSize alignmentOffset() const { return m_alignmentOffset; } 65 void setAlignmentOffset(const FloatSize& offset) { m_alignmentOffset = offset; } 66 67protected: 68 ViewportConstraints() 69 : m_anchorEdges(0) 70 { } 71 72 FloatSize m_alignmentOffset; 73 AnchorEdges m_anchorEdges; 74}; 75 76class FixedPositionViewportConstraints : public ViewportConstraints { 77public: 78 FixedPositionViewportConstraints() 79 : ViewportConstraints() 80 { } 81 82 FixedPositionViewportConstraints(const FixedPositionViewportConstraints& other) 83 : ViewportConstraints(other) 84 , m_viewportRectAtLastLayout(other.m_viewportRectAtLastLayout) 85 , m_layerPositionAtLastLayout(other.m_layerPositionAtLastLayout) 86 { } 87 88 FloatPoint layerPositionForViewportRect(const FloatRect& viewportRect) const; 89 90 const FloatRect& viewportRectAtLastLayout() const { return m_viewportRectAtLastLayout; } 91 void setViewportRectAtLastLayout(const FloatRect& rect) { m_viewportRectAtLastLayout = rect; } 92 93 const FloatPoint& layerPositionAtLastLayout() const { return m_layerPositionAtLastLayout; } 94 void setLayerPositionAtLastLayout(const FloatPoint& point) { m_layerPositionAtLastLayout = point; } 95 96 bool operator==(const FixedPositionViewportConstraints& other) const 97 { 98 return m_alignmentOffset == other.m_alignmentOffset 99 && m_anchorEdges == other.m_anchorEdges 100 && m_viewportRectAtLastLayout == other.m_viewportRectAtLastLayout 101 && m_layerPositionAtLastLayout == other.m_layerPositionAtLastLayout; 102 } 103 104 bool operator!=(const FixedPositionViewportConstraints& other) const { return !(*this == other); } 105 106private: 107 virtual ConstraintType constraintType() const override { return FixedPositionConstraint; }; 108 109 FloatRect m_viewportRectAtLastLayout; 110 FloatPoint m_layerPositionAtLastLayout; 111}; 112 113class StickyPositionViewportConstraints : public ViewportConstraints { 114public: 115 StickyPositionViewportConstraints() 116 : m_leftOffset(0) 117 , m_rightOffset(0) 118 , m_topOffset(0) 119 , m_bottomOffset(0) 120 { } 121 122 StickyPositionViewportConstraints(const StickyPositionViewportConstraints& other) 123 : ViewportConstraints(other) 124 , m_leftOffset(other.m_leftOffset) 125 , m_rightOffset(other.m_rightOffset) 126 , m_topOffset(other.m_topOffset) 127 , m_bottomOffset(other.m_bottomOffset) 128 , m_constrainingRectAtLastLayout(other.m_constrainingRectAtLastLayout) 129 , m_containingBlockRect(other.m_containingBlockRect) 130 , m_stickyBoxRect(other.m_stickyBoxRect) 131 , m_stickyOffsetAtLastLayout(other.m_stickyOffsetAtLastLayout) 132 , m_layerPositionAtLastLayout(other.m_layerPositionAtLastLayout) 133 { } 134 135 FloatSize computeStickyOffset(const FloatRect& constrainingRect) const; 136 137 const FloatSize stickyOffsetAtLastLayout() const { return m_stickyOffsetAtLastLayout; } 138 void setStickyOffsetAtLastLayout(const FloatSize& offset) { m_stickyOffsetAtLastLayout = offset; } 139 140 FloatPoint layerPositionForConstrainingRect(const FloatRect& constrainingRect) const; 141 142 const FloatPoint& layerPositionAtLastLayout() const { return m_layerPositionAtLastLayout; } 143 void setLayerPositionAtLastLayout(const FloatPoint& point) { m_layerPositionAtLastLayout = point; } 144 145 float leftOffset() const { return m_leftOffset; } 146 float rightOffset() const { return m_rightOffset; } 147 float topOffset() const { return m_topOffset; } 148 float bottomOffset() const { return m_bottomOffset; } 149 150 void setLeftOffset(float offset) { m_leftOffset = offset; } 151 void setRightOffset(float offset) { m_rightOffset = offset; } 152 void setTopOffset(float offset) { m_topOffset = offset; } 153 void setBottomOffset(float offset) { m_bottomOffset = offset; } 154 155 // constrainingRectAtLastLayout() is the viewport rect if this sticky object sticks to the viewport, and 156 // it is the overflow area's scrolled clip rect if this sticky object sticks inside an overflow area. 157 FloatRect constrainingRectAtLastLayout() const { return m_constrainingRectAtLastLayout; } 158 void setConstrainingRectAtLastLayout(const FloatRect& rect) { m_constrainingRectAtLastLayout = rect; } 159 160 // containingBlockRect() is in the scrolling ancestor's coordinate space. 161 FloatRect containingBlockRect() const { return m_containingBlockRect; } 162 void setContainingBlockRect(const FloatRect& rect) { m_containingBlockRect = rect; } 163 164 // stickyBoxRect() is in the scrolling ancestor's coordinate space. 165 FloatRect stickyBoxRect() const { return m_stickyBoxRect; } 166 void setStickyBoxRect(const FloatRect& rect) { m_stickyBoxRect = rect; } 167 168 bool operator==(const StickyPositionViewportConstraints& other) const 169 { 170 return m_alignmentOffset == other.m_alignmentOffset 171 && m_anchorEdges == other.m_anchorEdges 172 && m_leftOffset == other.m_leftOffset 173 && m_rightOffset == other.m_rightOffset 174 && m_topOffset == other.m_topOffset 175 && m_bottomOffset == other.m_bottomOffset 176 && m_containingBlockRect == other.m_containingBlockRect 177 && m_stickyBoxRect == other.m_stickyBoxRect 178 && m_stickyOffsetAtLastLayout == other.m_stickyOffsetAtLastLayout 179 && m_layerPositionAtLastLayout == other.m_layerPositionAtLastLayout; 180 } 181 182 bool operator!=(const StickyPositionViewportConstraints& other) const { return !(*this == other); } 183 184private: 185 virtual ConstraintType constraintType() const override { return StickyPositionConstraint; }; 186 187 float m_leftOffset; 188 float m_rightOffset; 189 float m_topOffset; 190 float m_bottomOffset; 191 FloatRect m_constrainingRectAtLastLayout; 192 FloatRect m_containingBlockRect; 193 FloatRect m_stickyBoxRect; 194 FloatSize m_stickyOffsetAtLastLayout; 195 FloatPoint m_layerPositionAtLastLayout; 196}; 197 198} // namespace WebCore 199 200#endif // ScrollingConstraints_h 201