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 "ScrollingConstraints.h"
28
29#include <wtf/text/TextStream.h>
30
31namespace WebCore {
32
33FloatPoint FixedPositionViewportConstraints::layerPositionForViewportRect(const FloatRect& viewportRect) const
34{
35 FloatSize offset;
36
37 if (hasAnchorEdge(AnchorEdgeLeft))
38 offset.setWidth(viewportRect.x() - m_viewportRectAtLastLayout.x());
39 else if (hasAnchorEdge(AnchorEdgeRight))
40 offset.setWidth(viewportRect.maxX() - m_viewportRectAtLastLayout.maxX());
41
42 if (hasAnchorEdge(AnchorEdgeTop))
43 offset.setHeight(viewportRect.y() - m_viewportRectAtLastLayout.y());
44 else if (hasAnchorEdge(AnchorEdgeBottom))
45 offset.setHeight(viewportRect.maxY() - m_viewportRectAtLastLayout.maxY());
46
47 return m_layerPositionAtLastLayout + offset;
48}
49
50FloatSize StickyPositionViewportConstraints::computeStickyOffset(const FloatRect& constrainingRect) const
51{
52 FloatRect boxRect = m_stickyBoxRect;
53
54 if (hasAnchorEdge(AnchorEdgeRight)) {
55 float rightLimit = constrainingRect.maxX() - m_rightOffset;
56 float rightDelta = std::min<float>(0, rightLimit - m_stickyBoxRect.maxX());
57 float availableSpace = std::min<float>(0, m_containingBlockRect.x() - m_stickyBoxRect.x());
58 if (rightDelta < availableSpace)
59 rightDelta = availableSpace;
60
61 boxRect.move(rightDelta, 0);
62 }
63
64 if (hasAnchorEdge(AnchorEdgeLeft)) {
65 float leftLimit = constrainingRect.x() + m_leftOffset;
66 float leftDelta = std::max<float>(0, leftLimit - m_stickyBoxRect.x());
67 float availableSpace = std::max<float>(0, m_containingBlockRect.maxX() - m_stickyBoxRect.maxX());
68 if (leftDelta > availableSpace)
69 leftDelta = availableSpace;
70
71 boxRect.move(leftDelta, 0);
72 }
73
74 if (hasAnchorEdge(AnchorEdgeBottom)) {
75 float bottomLimit = constrainingRect.maxY() - m_bottomOffset;
76 float bottomDelta = std::min<float>(0, bottomLimit - m_stickyBoxRect.maxY());
77 float availableSpace = std::min<float>(0, m_containingBlockRect.y() - m_stickyBoxRect.y());
78 if (bottomDelta < availableSpace)
79 bottomDelta = availableSpace;
80
81 boxRect.move(0, bottomDelta);
82 }
83
84 if (hasAnchorEdge(AnchorEdgeTop)) {
85 float topLimit = constrainingRect.y() + m_topOffset;
86 float topDelta = std::max<float>(0, topLimit - m_stickyBoxRect.y());
87 float availableSpace = std::max<float>(0, m_containingBlockRect.maxY() - m_stickyBoxRect.maxY());
88 if (topDelta > availableSpace)
89 topDelta = availableSpace;
90
91 boxRect.move(0, topDelta);
92 }
93
94 return boxRect.location() - m_stickyBoxRect.location();
95}
96
97FloatPoint StickyPositionViewportConstraints::layerPositionForConstrainingRect(const FloatRect& constrainingRect) const
98{
99 FloatSize offset = computeStickyOffset(constrainingRect);
100 return m_layerPositionAtLastLayout + offset - m_stickyOffsetAtLastLayout;
101}
102
103TextStream& operator<<(TextStream& ts, ScrollPositioningBehavior behavior)
104{
105 switch (behavior) {
106 case ScrollPositioningBehavior::None: ts << "none"; break;
107 case ScrollPositioningBehavior::Stationary: ts << "stationary"; break;
108 case ScrollPositioningBehavior::Moves: ts << "moves"; break;
109 }
110 return ts;
111}
112
113TextStream& operator<<(TextStream& ts, const LayoutConstraints& constraints)
114{
115 ts.dumpProperty("layer-position-at-last-layout", constraints.layerPositionAtLastLayout());
116 ts.dumpProperty("positioning-behavior", constraints.scrollPositioningBehavior());
117
118 return ts;
119}
120
121TextStream& operator<<(TextStream& ts, const FixedPositionViewportConstraints& constraints)
122{
123 ts.dumpProperty("viewport-rect-at-last-layout", constraints.viewportRectAtLastLayout());
124 ts.dumpProperty("layer-position-at-last-layout", constraints.layerPositionAtLastLayout());
125
126 return ts;
127}
128
129TextStream& operator<<(TextStream& ts, const StickyPositionViewportConstraints& constraints)
130{
131 ts.dumpProperty("sticky-position-at-last-layout", constraints.stickyOffsetAtLastLayout());
132 ts.dumpProperty("layer-position-at-last-layout", constraints.layerPositionAtLastLayout());
133
134 return ts;
135}
136
137} // namespace WebCore
138