Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "FrameMetrics.h"
8
9
#include "nsStyleConsts.h"
10
#include "nsStyleStruct.h"
11
#include "mozilla/WritingModes.h"
12
13
namespace mozilla {
14
namespace layers {
15
16
const ScrollableLayerGuid::ViewID ScrollableLayerGuid::NULL_SCROLL_ID = 0;
17
18
void FrameMetrics::RecalculateLayoutViewportOffset() {
19
if (!mIsRootContent) {
20
return;
21
}
22
KeepLayoutViewportEnclosingVisualViewport(GetVisualViewport(),
23
mScrollableRect, mLayoutViewport);
24
}
25
26
/* static */
27
void FrameMetrics::KeepLayoutViewportEnclosingVisualViewport(
28
const CSSRect& aVisualViewport, const CSSRect& aScrollableRect,
29
CSSRect& aLayoutViewport) {
30
// If the visual viewport is contained within the layout viewport, we don't
31
// need to make any adjustments, so we can exit early.
32
//
33
// Additionally, if the composition bounds changes (due to an orientation
34
// change, window resize, etc.), it may take a few frames for aLayoutViewport
35
// to update and during that time, the visual viewport may be larger than the
36
// layout viewport. In such situations, we take an early exit if the visual
37
// viewport contains the layout viewport.
38
if (aLayoutViewport.Contains(aVisualViewport) ||
39
aVisualViewport.Contains(aLayoutViewport)) {
40
return;
41
}
42
43
// If visual viewport size is greater than the layout viewport, move the
44
// layout viewport such that it remains inside the visual viewport. Otherwise,
45
// move the layout viewport such that the visual viewport is contained
46
// inside the layout viewport.
47
if ((aLayoutViewport.Width() < aVisualViewport.Width() &&
48
!FuzzyEqualsMultiplicative(aLayoutViewport.Width(),
49
aVisualViewport.Width())) ||
50
(aLayoutViewport.Height() < aVisualViewport.Height() &&
51
!FuzzyEqualsMultiplicative(aLayoutViewport.Height(),
52
aVisualViewport.Height()))) {
53
if (aLayoutViewport.X() < aVisualViewport.X()) {
54
// layout viewport moves right
55
aLayoutViewport.MoveToX(aVisualViewport.X());
56
} else if (aVisualViewport.XMost() < aLayoutViewport.XMost()) {
57
// layout viewport moves left
58
aLayoutViewport.MoveByX(aVisualViewport.XMost() -
59
aLayoutViewport.XMost());
60
}
61
if (aLayoutViewport.Y() < aVisualViewport.Y()) {
62
// layout viewport moves down
63
aLayoutViewport.MoveToY(aVisualViewport.Y());
64
} else if (aVisualViewport.YMost() < aLayoutViewport.YMost()) {
65
// layout viewport moves up
66
aLayoutViewport.MoveByY(aVisualViewport.YMost() -
67
aLayoutViewport.YMost());
68
}
69
} else {
70
if (aVisualViewport.X() < aLayoutViewport.X()) {
71
aLayoutViewport.MoveToX(aVisualViewport.X());
72
} else if (aLayoutViewport.XMost() < aVisualViewport.XMost()) {
73
aLayoutViewport.MoveByX(aVisualViewport.XMost() -
74
aLayoutViewport.XMost());
75
}
76
if (aVisualViewport.Y() < aLayoutViewport.Y()) {
77
aLayoutViewport.MoveToY(aVisualViewport.Y());
78
} else if (aLayoutViewport.YMost() < aVisualViewport.YMost()) {
79
aLayoutViewport.MoveByY(aVisualViewport.YMost() -
80
aLayoutViewport.YMost());
81
}
82
}
83
84
// Regardless of any adjustment above, the layout viewport is not allowed
85
// to go outside the scrollable rect.
86
aLayoutViewport = aLayoutViewport.MoveInsideAndClamp(aScrollableRect);
87
}
88
89
ScrollSnapInfo::ScrollSnapInfo()
90
: mScrollSnapStrictnessX(StyleScrollSnapStrictness::None),
91
mScrollSnapStrictnessY(StyleScrollSnapStrictness::None) {}
92
93
bool ScrollSnapInfo::HasScrollSnapping() const {
94
return mScrollSnapStrictnessY != StyleScrollSnapStrictness::None ||
95
mScrollSnapStrictnessX != StyleScrollSnapStrictness::None;
96
}
97
98
bool ScrollSnapInfo::HasSnapPositions() const {
99
return (!mSnapPositionX.IsEmpty() &&
100
mScrollSnapStrictnessX != StyleScrollSnapStrictness::None) ||
101
(!mSnapPositionY.IsEmpty() &&
102
mScrollSnapStrictnessY != StyleScrollSnapStrictness::None);
103
}
104
105
void ScrollSnapInfo::InitializeScrollSnapStrictness(
106
WritingMode aWritingMode, const nsStyleDisplay* aDisplay) {
107
if (aDisplay->mScrollSnapType.strictness == StyleScrollSnapStrictness::None) {
108
return;
109
}
110
111
mScrollSnapStrictnessX = StyleScrollSnapStrictness::None;
112
mScrollSnapStrictnessY = StyleScrollSnapStrictness::None;
113
114
switch (aDisplay->mScrollSnapType.axis) {
115
case StyleScrollSnapAxis::X:
116
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
117
break;
118
case StyleScrollSnapAxis::Y:
119
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
120
break;
121
case StyleScrollSnapAxis::Block:
122
if (aWritingMode.IsVertical()) {
123
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
124
} else {
125
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
126
}
127
break;
128
case StyleScrollSnapAxis::Inline:
129
if (aWritingMode.IsVertical()) {
130
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
131
} else {
132
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
133
}
134
break;
135
case StyleScrollSnapAxis::Both:
136
mScrollSnapStrictnessX = aDisplay->mScrollSnapType.strictness;
137
mScrollSnapStrictnessY = aDisplay->mScrollSnapType.strictness;
138
break;
139
}
140
}
141
142
static OverscrollBehavior ToOverscrollBehavior(
143
StyleOverscrollBehavior aBehavior) {
144
switch (aBehavior) {
145
case StyleOverscrollBehavior::Auto:
146
return OverscrollBehavior::Auto;
147
case StyleOverscrollBehavior::Contain:
148
return OverscrollBehavior::Contain;
149
case StyleOverscrollBehavior::None:
150
return OverscrollBehavior::None;
151
}
152
MOZ_ASSERT_UNREACHABLE("Invalid overscroll behavior");
153
return OverscrollBehavior::Auto;
154
}
155
156
OverscrollBehaviorInfo OverscrollBehaviorInfo::FromStyleConstants(
157
StyleOverscrollBehavior aBehaviorX, StyleOverscrollBehavior aBehaviorY) {
158
OverscrollBehaviorInfo result;
159
result.mBehaviorX = ToOverscrollBehavior(aBehaviorX);
160
result.mBehaviorY = ToOverscrollBehavior(aBehaviorY);
161
return result;
162
}
163
164
void ScrollMetadata::SetBackgroundColor(const gfx::sRGBColor& aBackgroundColor) {
165
mBackgroundColor = ToDeviceColor(aBackgroundColor);
166
}
167
168
StaticAutoPtr<const ScrollMetadata> ScrollMetadata::sNullMetadata;
169
170
} // namespace layers
171
} // namespace mozilla