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 #include "config.h" 27 #include "core/page/scrolling/ScrollingConstraints.h" 28 29 namespace WebCore { 30 31 FloatPoint FixedPositionViewportConstraints::layerPositionForViewportRect(const FloatRect& viewportRect) const 32 { 33 FloatSize offset; 34 35 if (hasAnchorEdge(AnchorEdgeLeft)) 36 offset.setWidth(viewportRect.x() - m_viewportRectAtLastLayout.x()); 37 else if (hasAnchorEdge(AnchorEdgeRight)) 38 offset.setWidth(viewportRect.maxX() - m_viewportRectAtLastLayout.maxX()); 39 40 if (hasAnchorEdge(AnchorEdgeTop)) 41 offset.setHeight(viewportRect.y() - m_viewportRectAtLastLayout.y()); 42 else if (hasAnchorEdge(AnchorEdgeBottom)) 43 offset.setHeight(viewportRect.maxY() - m_viewportRectAtLastLayout.maxY()); 44 45 return m_layerPositionAtLastLayout + offset; 46 } 47 48 FloatSize StickyPositionViewportConstraints::computeStickyOffset(const FloatRect& viewportRect) const 49 { 50 FloatRect boxRect = m_absoluteStickyBoxRect; 51 52 if (hasAnchorEdge(AnchorEdgeRight)) { 53 float rightLimit = viewportRect.maxX() - m_rightOffset; 54 float rightDelta = std::min<float>(0, rightLimit - m_absoluteStickyBoxRect.maxX()); 55 float availableSpace = std::min<float>(0, m_absoluteContainingBlockRect.x() - m_absoluteStickyBoxRect.x()); 56 if (rightDelta < availableSpace) 57 rightDelta = availableSpace; 58 59 boxRect.move(rightDelta, 0); 60 } 61 62 if (hasAnchorEdge(AnchorEdgeLeft)) { 63 float leftLimit = viewportRect.x() + m_leftOffset; 64 float leftDelta = std::max<float>(0, leftLimit - m_absoluteStickyBoxRect.x()); 65 float availableSpace = std::max<float>(0, m_absoluteContainingBlockRect.maxX() - m_absoluteStickyBoxRect.maxX()); 66 if (leftDelta > availableSpace) 67 leftDelta = availableSpace; 68 69 boxRect.move(leftDelta, 0); 70 } 71 72 if (hasAnchorEdge(AnchorEdgeBottom)) { 73 float bottomLimit = viewportRect.maxY() - m_bottomOffset; 74 float bottomDelta = std::min<float>(0, bottomLimit - m_absoluteStickyBoxRect.maxY()); 75 float availableSpace = std::min<float>(0, m_absoluteContainingBlockRect.y() - m_absoluteStickyBoxRect.y()); 76 if (bottomDelta < availableSpace) 77 bottomDelta = availableSpace; 78 79 boxRect.move(0, bottomDelta); 80 } 81 82 if (hasAnchorEdge(AnchorEdgeTop)) { 83 float topLimit = viewportRect.y() + m_topOffset; 84 float topDelta = std::max<float>(0, topLimit - m_absoluteStickyBoxRect.y()); 85 float availableSpace = std::max<float>(0, m_absoluteContainingBlockRect.maxY() - m_absoluteStickyBoxRect.maxY()); 86 if (topDelta > availableSpace) 87 topDelta = availableSpace; 88 89 boxRect.move(0, topDelta); 90 } 91 92 return boxRect.location() - m_absoluteStickyBoxRect.location(); 93 } 94 95 FloatPoint StickyPositionViewportConstraints::layerPositionForViewportRect(const FloatRect& viewportRect) const 96 { 97 FloatSize offset = computeStickyOffset(viewportRect); 98 return m_layerPositionAtLastLayout + offset - m_stickyOffsetAtLastLayout; 99 } 100 101 } // namespace WebCore 102