Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: third_party/WebKit/Source/core/frame/RootFrameViewport.cpp

Issue 2387883002: Use float for scroll offset. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/RootFrameViewport.h" 5 #include "core/frame/RootFrameViewport.h"
6 6
7 #include "core/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "core/layout/ScrollAlignment.h" 8 #include "core/layout/ScrollAlignment.h"
9 #include "core/layout/ScrollAnchor.h" 9 #include "core/layout/ScrollAnchor.h"
10 #include "platform/geometry/DoubleRect.h" 10 #include "platform/geometry/DoubleRect.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 // If the root FrameView is the layout viewport then coordinates in the 42 // If the root FrameView is the layout viewport then coordinates in the
43 // root FrameView's content space are already in the layout viewport's 43 // root FrameView's content space are already in the layout viewport's
44 // content space. 44 // content space.
45 if (rootFrameView.layoutViewportScrollableArea() == &layoutViewport()) 45 if (rootFrameView.layoutViewportScrollableArea() == &layoutViewport())
46 return ret; 46 return ret;
47 47
48 // Make the given rect relative to the top of the layout viewport's content 48 // Make the given rect relative to the top of the layout viewport's content
49 // by adding the scroll position. 49 // by adding the scroll position.
50 // TODO(bokan): This will have to be revisited if we ever remove the 50 // TODO(bokan): This will have to be revisited if we ever remove the
51 // restriction that a root scroller must be exactly screen filling. 51 // restriction that a root scroller must be exactly screen filling.
52 ret.moveBy(LayoutPoint(layoutViewport().scrollPositionDouble())); 52 ret.moveBy(LayoutPoint(FloatPoint((layoutViewport().scrollOffset()))));
bokan 2016/10/02 19:47:51 ret.move()
szager1 2016/10/05 07:43:36 Done.
53 53
54 return ret; 54 return ret;
55 } 55 }
56 56
57 void RootFrameViewport::restoreToAnchor(const DoublePoint& targetPosition) { 57 void RootFrameViewport::restoreToAnchor(const ScrollOffset& targetOffset) {
58 // Clamp the scroll offset of each viewport now so that we force any invalid 58 // Clamp the scroll offset of each viewport now so that we force any invalid
59 // offsets to become valid so we can compute the correct deltas. 59 // offsets to become valid so we can compute the correct deltas.
60 visualViewport().setScrollPosition(visualViewport().scrollPositionDouble(), 60 visualViewport().setScrollOffset(visualViewport().scrollOffset(),
61 ProgrammaticScroll); 61 ProgrammaticScroll);
62 layoutViewport().setScrollPosition(layoutViewport().scrollPositionDouble(), 62 layoutViewport().setScrollOffset(layoutViewport().scrollOffset(),
63 ProgrammaticScroll); 63 ProgrammaticScroll);
64 64
65 DoubleSize delta = targetPosition - scrollPositionDouble(); 65 ScrollOffset delta = targetOffset - scrollOffset();
66 66
67 visualViewport().setScrollPosition( 67 visualViewport().setScrollOffset(visualViewport().scrollOffset() + delta,
68 visualViewport().scrollPositionDouble() + delta, ProgrammaticScroll); 68 ProgrammaticScroll);
69 69
70 delta = targetPosition - scrollPositionDouble(); 70 delta = targetOffset - scrollOffset();
71 71
72 // Since the main thread FrameView has integer scroll offsets, scroll it to 72 // Since the main thread FrameView has integer scroll offsets, scroll it to
73 // the next pixel and then we'll scroll the visual viewport again to 73 // the next pixel and then we'll scroll the visual viewport again to
74 // compensate for the sub-pixel offset. We need this "overscroll" to ensure 74 // compensate for the sub-pixel offset. We need this "overscroll" to ensure
75 // the pixel of which we want to be partially in appears fully inside the 75 // the pixel of which we want to be partially in appears fully inside the
76 // FrameView since the VisualViewport is bounded by the FrameView. 76 // FrameView since the VisualViewport is bounded by the FrameView.
77 IntSize layoutDelta = IntSize( 77 IntSize layoutDelta = IntSize(
78 delta.width() < 0 ? floor(delta.width()) : ceil(delta.width()), 78 delta.width() < 0 ? floor(delta.width()) : ceil(delta.width()),
79 delta.height() < 0 ? floor(delta.height()) : ceil(delta.height())); 79 delta.height() < 0 ? floor(delta.height()) : ceil(delta.height()));
80 80
81 layoutViewport().setScrollPosition( 81 layoutViewport().setScrollOffset(
82 layoutViewport().scrollPosition() + layoutDelta, ProgrammaticScroll); 82 ScrollOffset(layoutViewport().scrollOffsetInt() + layoutDelta),
83 ProgrammaticScroll);
83 84
84 delta = targetPosition - scrollPositionDouble(); 85 delta = targetOffset - scrollOffset();
85 visualViewport().setScrollPosition( 86 visualViewport().setScrollOffset(visualViewport().scrollOffset() + delta,
86 visualViewport().scrollPositionDouble() + delta, ProgrammaticScroll); 87 ProgrammaticScroll);
87 } 88 }
88 89
89 void RootFrameViewport::didUpdateVisualViewport() { 90 void RootFrameViewport::didUpdateVisualViewport() {
90 if (RuntimeEnabledFeatures::scrollAnchoringEnabled()) { 91 if (RuntimeEnabledFeatures::scrollAnchoringEnabled()) {
91 if (ScrollAnchor* anchor = layoutViewport().scrollAnchor()) 92 if (ScrollAnchor* anchor = layoutViewport().scrollAnchor())
92 anchor->clear(); 93 anchor->clear();
93 } 94 }
94 } 95 }
95 96
96 LayoutBox* RootFrameViewport::layoutBox() const { 97 LayoutBox* RootFrameViewport::layoutBox() const {
97 return layoutViewport().layoutBox(); 98 return layoutViewport().layoutBox();
98 } 99 }
99 100
100 void RootFrameViewport::updateScrollAnimator() { 101 void RootFrameViewport::updateScrollAnimator() {
101 scrollAnimator().setCurrentPosition( 102 scrollAnimator().setCurrentOffset(
102 toFloatPoint(scrollOffsetFromScrollAnimators())); 103 toFloatSize(scrollOffsetFromScrollAnimators()));
103 } 104 }
104 105
105 DoublePoint RootFrameViewport::scrollOffsetFromScrollAnimators() const { 106 ScrollOffset RootFrameViewport::scrollOffsetFromScrollAnimators() const {
106 return visualViewport().scrollAnimator().currentPosition() + 107 return visualViewport().scrollAnimator().currentOffset() +
107 layoutViewport().scrollAnimator().currentPosition(); 108 layoutViewport().scrollAnimator().currentOffset();
108 }
109
110 DoubleRect RootFrameViewport::visibleContentRectDouble(
111 IncludeScrollbarsInRect scrollbarInclusion) const {
112 return DoubleRect(
113 scrollPositionDouble(),
114 visualViewport().visibleContentRectDouble(scrollbarInclusion).size());
115 } 109 }
116 110
117 IntRect RootFrameViewport::visibleContentRect( 111 IntRect RootFrameViewport::visibleContentRect(
118 IncludeScrollbarsInRect scrollbarInclusion) const { 112 IncludeScrollbarsInRect scrollbarInclusion) const {
119 return enclosingIntRect(visibleContentRectDouble(scrollbarInclusion)); 113 return IntRect(
114 IntPoint(scrollOffsetInt()),
115 visualViewport().visibleContentRect(scrollbarInclusion).size());
120 } 116 }
121 117
122 bool RootFrameViewport::shouldUseIntegerScrollOffset() const { 118 bool RootFrameViewport::shouldUseIntegerScrollOffset() const {
123 // Fractionals are floored in the ScrollAnimatorBase but it's important that t he ScrollAnimators of the 119 // Fractionals are floored in the ScrollAnimatorBase but it's important that t he ScrollAnimators of the
124 // visual and layout viewports get the precise fractional number so never use integer scrolling for 120 // visual and layout viewports get the precise fractional number so never use integer scrolling for
125 // RootFrameViewport, we'll let the truncation happen in the subviewports. 121 // RootFrameViewport, we'll let the truncation happen in the subviewports.
126 return false; 122 return false;
127 } 123 }
128 124
129 bool RootFrameViewport::isActive() const { 125 bool RootFrameViewport::isActive() const {
130 return layoutViewport().isActive(); 126 return layoutViewport().isActive();
131 } 127 }
132 128
133 int RootFrameViewport::scrollSize(ScrollbarOrientation orientation) const { 129 int RootFrameViewport::scrollSize(ScrollbarOrientation orientation) const {
134 IntSize scrollDimensions = maximumScrollPosition() - minimumScrollPosition(); 130 IntSize scrollDimensions =
131 maximumScrollOffsetInt() - minimumScrollOffsetInt();
135 return (orientation == HorizontalScrollbar) ? scrollDimensions.width() 132 return (orientation == HorizontalScrollbar) ? scrollDimensions.width()
136 : scrollDimensions.height(); 133 : scrollDimensions.height();
137 } 134 }
138 135
139 bool RootFrameViewport::isScrollCornerVisible() const { 136 bool RootFrameViewport::isScrollCornerVisible() const {
140 return layoutViewport().isScrollCornerVisible(); 137 return layoutViewport().isScrollCornerVisible();
141 } 138 }
142 139
143 IntRect RootFrameViewport::scrollCornerRect() const { 140 IntRect RootFrameViewport::scrollCornerRect() const {
144 return layoutViewport().scrollCornerRect(); 141 return layoutViewport().scrollCornerRect();
145 } 142 }
146 143
147 void RootFrameViewport::setScrollPosition(const DoublePoint& position, 144 void RootFrameViewport::setScrollOffset(const ScrollOffset& offset,
148 ScrollType scrollType, 145 ScrollType scrollType,
149 ScrollBehavior scrollBehavior) { 146 ScrollBehavior scrollBehavior) {
150 updateScrollAnimator(); 147 updateScrollAnimator();
151 148
152 if (scrollBehavior == ScrollBehaviorAuto) 149 if (scrollBehavior == ScrollBehaviorAuto)
153 scrollBehavior = scrollBehaviorStyle(); 150 scrollBehavior = scrollBehaviorStyle();
154 151
155 if (scrollType == ProgrammaticScroll && 152 if (scrollType == ProgrammaticScroll &&
156 !layoutViewport().isProgrammaticallyScrollable()) 153 !layoutViewport().isProgrammaticallyScrollable())
157 return; 154 return;
158 155
159 if (scrollType == AnchoringScroll) { 156 if (scrollType == AnchoringScroll) {
160 distributeScrollBetweenViewports(position, scrollType, scrollBehavior, 157 distributeScrollBetweenViewports(offset, scrollType, scrollBehavior,
161 LayoutViewport); 158 LayoutViewport);
162 return; 159 return;
163 } 160 }
164 161
165 if (scrollBehavior == ScrollBehaviorSmooth) { 162 if (scrollBehavior == ScrollBehaviorSmooth) {
166 distributeScrollBetweenViewports(position, scrollType, scrollBehavior, 163 distributeScrollBetweenViewports(offset, scrollType, scrollBehavior,
167 VisualViewport); 164 VisualViewport);
168 return; 165 return;
169 } 166 }
170 167
171 DoublePoint clampedPosition = clampScrollPosition(position); 168 ScrollOffset clampedOffset = clampScrollOffset(offset);
172 ScrollableArea::setScrollPosition(clampedPosition, scrollType, 169 ScrollableArea::setScrollOffset(clampedOffset, scrollType, scrollBehavior);
173 scrollBehavior);
174 } 170 }
175 171
176 ScrollBehavior RootFrameViewport::scrollBehaviorStyle() const { 172 ScrollBehavior RootFrameViewport::scrollBehaviorStyle() const {
177 return layoutViewport().scrollBehaviorStyle(); 173 return layoutViewport().scrollBehaviorStyle();
178 } 174 }
179 175
180 LayoutRect RootFrameViewport::scrollIntoView(const LayoutRect& rectInContent, 176 LayoutRect RootFrameViewport::scrollIntoView(const LayoutRect& rectInContent,
181 const ScrollAlignment& alignX, 177 const ScrollAlignment& alignX,
182 const ScrollAlignment& alignY, 178 const ScrollAlignment& alignY,
183 ScrollType scrollType) { 179 ScrollType scrollType) {
184 // We want to move the rect into the viewport that excludes the scrollbars so we intersect 180 // We want to move the rect into the viewport that excludes the scrollbars so we intersect
185 // the visual viewport with the scrollbar-excluded frameView content rect. How ever, we don't 181 // the visual viewport with the scrollbar-excluded frameView content rect. How ever, we don't
186 // use visibleContentRect directly since it floors the scroll position. Instea d, we use 182 // use visibleContentRect directly since it floors the scroll offset. Instead, we use
187 // ScrollAnimatorBase::currentPosition and construct a LayoutRect from that. 183 // ScrollAnimatorBase::currentOffset and construct a LayoutRect from that.
188 184
189 LayoutRect frameRectInContent = 185 LayoutRect frameRectInContent =
190 LayoutRect(layoutViewport().scrollAnimator().currentPosition(), 186 LayoutRect(FloatPoint(layoutViewport().scrollAnimator().currentOffset()),
191 layoutViewport().visibleContentRect().size()); 187 FloatSize(layoutViewport().visibleContentRect().size()));
192 LayoutRect visualRectInContent = 188 LayoutRect visualRectInContent =
193 LayoutRect(scrollOffsetFromScrollAnimators(), 189 LayoutRect(FloatPoint(scrollOffsetFromScrollAnimators()),
194 visualViewport().visibleContentRect().size()); 190 FloatSize(visualViewport().visibleContentRect().size()));
195 191
196 // Intersect layout and visual rects to exclude the scrollbar from the view re ct. 192 // Intersect layout and visual rects to exclude the scrollbar from the view re ct.
197 LayoutRect viewRectInContent = 193 LayoutRect viewRectInContent =
198 intersection(visualRectInContent, frameRectInContent); 194 intersection(visualRectInContent, frameRectInContent);
199 LayoutRect targetViewport = ScrollAlignment::getRectToExpose( 195 LayoutRect targetViewport = ScrollAlignment::getRectToExpose(
200 viewRectInContent, rectInContent, alignX, alignY); 196 viewRectInContent, rectInContent, alignX, alignY);
201 if (targetViewport != viewRectInContent) 197 if (targetViewport != viewRectInContent) {
202 setScrollPosition(DoublePoint(targetViewport.x(), targetViewport.y()), 198 setScrollOffset(ScrollOffset(targetViewport.x(), targetViewport.y()),
203 scrollType); 199 scrollType);
200 }
204 201
205 // RootFrameViewport only changes the viewport relative to the document so we can't change the input 202 // RootFrameViewport only changes the viewport relative to the document so we can't change the input
206 // rect's location relative to the document origin. 203 // rect's location relative to the document origin.
207 return rectInContent; 204 return rectInContent;
208 } 205 }
209 206
210 void RootFrameViewport::updateScrollPosition(const DoublePoint& position, 207 void RootFrameViewport::updateScrollOffset(const ScrollOffset& offset,
211 ScrollType scrollType) { 208 ScrollType scrollType) {
212 distributeScrollBetweenViewports(DoublePoint(position), scrollType, 209 distributeScrollBetweenViewports(offset, scrollType, ScrollBehaviorInstant,
213 ScrollBehaviorInstant, VisualViewport); 210 VisualViewport);
214 } 211 }
215 212
216 void RootFrameViewport::distributeScrollBetweenViewports( 213 void RootFrameViewport::distributeScrollBetweenViewports(
217 const DoublePoint& position, 214 const ScrollOffset& offset,
218 ScrollType scrollType, 215 ScrollType scrollType,
219 ScrollBehavior behavior, 216 ScrollBehavior behavior,
220 ViewportToScrollFirst scrollFirst) { 217 ViewportToScrollFirst scrollFirst) {
221 // Make sure we use the scroll positions as reported by each viewport's Scroll AnimatorBase, since its 218 // Make sure we use the scroll offsets as reported by each viewport's ScrollAn imatorBase, since its
222 // ScrollableArea's position may have the fractional part truncated off. 219 // ScrollableArea's offset may have the fractional part truncated off.
bokan 2016/10/02 19:47:50 Please add a TODO to revisit this now that the off
szager1 2016/10/05 07:43:36 Done.
223 DoublePoint oldPosition = scrollOffsetFromScrollAnimators(); 220 ScrollOffset oldOffset = scrollOffsetFromScrollAnimators();
224 221
225 DoubleSize delta = position - oldPosition; 222 ScrollOffset delta = offset - oldOffset;
226 223
227 if (delta.isZero()) 224 if (delta.isZero())
228 return; 225 return;
229 226
230 ScrollableArea& primary = 227 ScrollableArea& primary =
231 scrollFirst == VisualViewport ? visualViewport() : layoutViewport(); 228 scrollFirst == VisualViewport ? visualViewport() : layoutViewport();
232 ScrollableArea& secondary = 229 ScrollableArea& secondary =
233 scrollFirst == VisualViewport ? layoutViewport() : visualViewport(); 230 scrollFirst == VisualViewport ? layoutViewport() : visualViewport();
234 231
235 DoublePoint targetPosition = primary.clampScrollPosition( 232 ScrollOffset targetOffset = primary.clampScrollOffset(
236 primary.scrollAnimator().currentPosition() + delta); 233 primary.scrollAnimator().currentOffset() + delta);
237 234
238 primary.setScrollPosition(targetPosition, scrollType, behavior); 235 primary.setScrollOffset(targetOffset, scrollType, behavior);
239 236
240 // Scroll the secondary viewport if all of the scroll was not applied to the 237 // Scroll the secondary viewport if all of the scroll was not applied to the
241 // primary viewport. 238 // primary viewport.
242 DoublePoint updatedPosition = 239 ScrollOffset updatedOffset =
243 secondary.scrollAnimator().currentPosition() + FloatPoint(targetPosition); 240 secondary.scrollAnimator().currentOffset() + FloatSize(targetOffset);
244 DoubleSize applied = updatedPosition - oldPosition; 241 ScrollOffset applied = updatedOffset - oldOffset;
245 delta -= applied; 242 delta -= applied;
246 243
247 if (delta.isZero()) 244 if (delta.isZero())
248 return; 245 return;
249 246
250 targetPosition = secondary.clampScrollPosition( 247 targetOffset = secondary.clampScrollOffset(
251 secondary.scrollAnimator().currentPosition() + delta); 248 secondary.scrollAnimator().currentOffset() + delta);
252 secondary.setScrollPosition(targetPosition, scrollType, behavior); 249 secondary.setScrollOffset(targetOffset, scrollType, behavior);
253 } 250 }
254 251
255 IntPoint RootFrameViewport::scrollPosition() const { 252 IntSize RootFrameViewport::scrollOffsetInt() const {
256 return flooredIntPoint(scrollPositionDouble()); 253 return flooredIntSize(scrollOffset());
257 } 254 }
258 255
259 DoublePoint RootFrameViewport::scrollPositionDouble() const { 256 ScrollOffset RootFrameViewport::scrollOffset() const {
260 return layoutViewport().scrollPositionDouble() + 257 return layoutViewport().scrollOffset() + visualViewport().scrollOffset();
261 toDoubleSize(visualViewport().scrollPositionDouble());
262 } 258 }
263 259
264 IntPoint RootFrameViewport::minimumScrollPosition() const { 260 IntSize RootFrameViewport::minimumScrollOffsetInt() const {
265 return IntPoint(layoutViewport().minimumScrollPosition() + 261 return IntSize(layoutViewport().minimumScrollOffsetInt() +
266 visualViewport().minimumScrollPosition()); 262 visualViewport().minimumScrollOffsetInt());
267 } 263 }
268 264
269 IntPoint RootFrameViewport::maximumScrollPosition() const { 265 IntSize RootFrameViewport::maximumScrollOffsetInt() const {
270 return layoutViewport().maximumScrollPosition() + 266 return layoutViewport().maximumScrollOffsetInt() +
271 visualViewport().maximumScrollPosition(); 267 visualViewport().maximumScrollOffsetInt();
272 } 268 }
273 269
274 DoublePoint RootFrameViewport::maximumScrollPositionDouble() const { 270 ScrollOffset RootFrameViewport::maximumScrollOffset() const {
275 return layoutViewport().maximumScrollPositionDouble() + 271 return layoutViewport().maximumScrollOffset() +
276 toDoubleSize(visualViewport().maximumScrollPositionDouble()); 272 visualViewport().maximumScrollOffset();
277 } 273 }
278 274
279 IntSize RootFrameViewport::contentsSize() const { 275 IntSize RootFrameViewport::contentsSize() const {
280 return layoutViewport().contentsSize(); 276 return layoutViewport().contentsSize();
281 } 277 }
282 278
283 bool RootFrameViewport::scrollbarsCanBeActive() const { 279 bool RootFrameViewport::scrollbarsCanBeActive() const {
284 return layoutViewport().scrollbarsCanBeActive(); 280 return layoutViewport().scrollbarsCanBeActive();
285 } 281 }
286 282
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 visualViewport().clearScrollAnimators(); 420 visualViewport().clearScrollAnimators();
425 } 421 }
426 422
427 DEFINE_TRACE(RootFrameViewport) { 423 DEFINE_TRACE(RootFrameViewport) {
428 visitor->trace(m_visualViewport); 424 visitor->trace(m_visualViewport);
429 visitor->trace(m_layoutViewport); 425 visitor->trace(m_layoutViewport);
430 ScrollableArea::trace(visitor); 426 ScrollableArea::trace(visitor);
431 } 427 }
432 428
433 } // namespace blink 429 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698