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

Side by Side Diff: cc/pinch_zoom_scrollbar_layer_impl.cc

Issue 11550035: Implement pinch-zoom scaling for main-frame scrollbars and pinch-zoom overlay scrollbars. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Refactor for cleaner state/scrollbar split. Created 7 years, 11 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/pinch_zoom_scrollbar_layer_impl.h"
6
7 #include "cc/layer_tree_host_impl.h"
8 #include "cc/layer_tree_impl.h"
9 #include "cc/quad_sink.h"
10 #include "cc/renderer.h"
11 #include "cc/texture_draw_quad.h"
12 #include "skia/ext/platform_canvas.h"
13 #include "ui/gfx/rect.h"
14 #include "ui/gfx/rect_conversions.h"
15
16 namespace cc {
17
18 PinchZoomScrollbarState::PinchZoomScrollbarState(
19 WebKit::WebScrollbar::Orientation orientation, PinchZoomViewport* owner)
20 : owner_(owner),
21 orientation_(orientation) {
22 DCHECK(owner_);
23 }
24
25 PinchZoomScrollbarState::~PinchZoomScrollbarState() {}
26
27 gfx::SizeF PinchZoomScrollbarState::layout_viewport_size() const {
28 return owner_->layout_viewport_size();
29 }
30
31 gfx::Vector2dF PinchZoomScrollbarState::zoomed_viewport_offset() const {
32 return owner_->zoomed_viewport_offset();
33 }
34
35 float PinchZoomScrollbarState::total_page_scale_factor() const {
36 return owner_->total_page_scale_factor();
37 }
38
39 float PinchZoomScrollbarState::device_scale_factor() const {
40 return owner_->device_scale_factor();
41 }
42
43 LayerImpl* PinchZoomScrollbarState::root_scroll_layer() {
44 return owner_->root_scroll_layer();
45 }
46
47 void PinchZoomScrollbarState::RefreshSizeAndPosition(LayerImpl* layer_impl)
48 {
49 gfx::SizeF size = owner_->layout_viewport_size();
50 if (orientation_ == WebKit::WebScrollbar::Vertical) {
51 gfx::Size bounds = gfx::Size(kTrackWidth, size.height());
52 layer_impl->setContentBounds(bounds);
53 layer_impl->setBounds(bounds);
54 layer_impl->setPosition(gfx::Point(size.width() - kTrackWidth, 0));
55 } else {
56 gfx::Size bounds = gfx::Size(size.width(), kTrackWidth);
57 layer_impl->setContentBounds(bounds);
58 layer_impl->setBounds(bounds);
59 layer_impl->setPosition(gfx::Point(0, size.height() - kTrackWidth));
60 }
61 }
62
63 bool PinchZoomScrollbarState::ShouldDisplayPinchZoomScrollbars() {
64 return owner_->total_page_scale_factor() > 1 && owner_->currently_scrolling_la yer();
65 }
66
67 scoped_ptr<PinchZoomScrollbarLayerImpl> PinchZoomScrollbarLayerImpl::create(
68 LayerTreeImpl* treeImpl,
69 int id,
70 PinchZoomScrollbarState* state) {
71 return make_scoped_ptr(new PinchZoomScrollbarLayerImpl(treeImpl, id, state));
72 }
73
74 PinchZoomScrollbarLayerImpl::PinchZoomScrollbarLayerImpl(
75 LayerTreeImpl* treeImpl,
76 int id, PinchZoomScrollbarState* state)
77 : ScrollbarLayerImplBase(treeImpl, id),
78 state_(state) {
79 DCHECK(state_);
80 std::string debugName = "Layer for Pinch Zoom Scrollbar ";
81 debugName += ((state_->orientation() == WebKit::WebScrollbar::Vertical) ?
82 "(vertical)" : "(horizontal)");
83 setDebugName(debugName);
84
85 state_->RefreshSizeAndPosition(this);
86 }
87
88 PinchZoomScrollbarLayerImpl::~PinchZoomScrollbarLayerImpl() {}
89
90 float PinchZoomScrollbarLayerImpl::currentPos() const {
91 return state_->thumb_position();
92 }
93
94 int PinchZoomScrollbarLayerImpl::totalSize() const {
95 return state_->track_length();
96 }
97
98 int PinchZoomScrollbarLayerImpl::maximum() const {
99 return state_->maximum_position();
100 }
101
102 WebKit::WebScrollbar::Orientation PinchZoomScrollbarLayerImpl::orientation()
103 const {
104 return state_->orientation();
105 }
106
107 void PinchZoomScrollbarLayerImpl::appendQuads(
108 QuadSink& quad_sink, AppendQuadsData& append_quads_data) {
109 if (!state_->ShouldDisplayPinchZoomScrollbars())
110 return;
111
112 if (state_->thumb_rect().IsEmpty() || !state_->thumb_texture()->id())
113 return;
114
115 bool premultipled_alpha = false;
116 bool flipped = false;
117 gfx::RectF uv_rect(0, 0, 1, 1);
118
119 SharedQuadState* shared_quad_state =
120 quad_sink.useSharedQuadState(createSharedQuadState());
121 appendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
122
123 gfx::Rect quad_rect(gfx::ToEnclosingRect(
124 gfx::ScaleRect(state_->thumb_rect(),
125 contentsScaleX(), contentsScaleY())));
126
127 gfx::Rect opaque_rect;
128 const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
129 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
130 quad->SetNew(shared_quad_state, quad_rect, opaque_rect,
131 state_->thumb_texture()->id(),
132 premultipled_alpha, uv_rect, opacity, flipped);
133 quad_sink.append(quad.PassAs<DrawQuad>(), append_quads_data);
134 }
135
136 void PinchZoomScrollbarLayerImpl::willDraw(
137 ResourceProvider* resource_provider) {
138 LayerImpl::willDraw(resource_provider);
139
140 if (!state_->ShouldDisplayPinchZoomScrollbars())
141 return;
142
143 gfx::Size layout_document_size(layerTreeImpl()->ContentSize());
144
145 gfx::SizeF layout_viewport_size = state_->layout_viewport_size();
146 gfx::Vector2dF layout_viewport_position = state_->zoomed_viewport_offset();
147 float page_scale_factor = state_->total_page_scale_factor();
148 float device_scale_factor = state_->device_scale_factor();
149
150 DCHECK(!layout_document_size.IsEmpty());
151
152 gfx::Vector2d root_scroll_offset;
153 gfx::Vector2d root_max_scroll_offset;
154 LayerImpl* root_scroll_layer = state_->root_scroll_layer();
155 if (root_scroll_layer) {
156 root_scroll_offset = root_scroll_layer->scrollOffset();
157 root_max_scroll_offset = root_scroll_layer->maxScrollOffset();
158 }
159
160 gfx::Rect new_thumb_rect;
161 int& track_length = state_->track_length();
162 float& thumb_position = state_->thumb_position();
163 int& maximum_position = state_->maximum_position();
164 int track_width = state_->track_width();
165
166 int thumb_length;
167 if (state_->orientation() == WebKit::WebScrollbar::Vertical) {
168 track_length = layout_viewport_size.height() - track_width;
169 thumb_length = layout_viewport_size.height() /
170 layout_document_size.height() * device_scale_factor * track_length;
171 maximum_position = state_->track_length() - thumb_length;
172
173 float max_offset = root_max_scroll_offset.y() + (page_scale_factor - 1)
174 / page_scale_factor * layout_viewport_size.height();
175 float offset = (max_offset >= 1) ? root_scroll_offset.y() +
176 layout_viewport_position.y() : 0;
177 thumb_position = offset / max_offset * maximum_position;
178
179 // Thumb rect position is with respect to the layer, so the x-coordinate
180 // should be 0.
181 new_thumb_rect = gfx::Rect(0, thumb_position, track_width, thumb_length);
182 } else {
183 track_length = layout_viewport_size.width() - track_width;
184 thumb_length = layout_viewport_size.width() / layout_document_size.width() *
185 device_scale_factor * track_length;
186 maximum_position = track_length - thumb_length;
187
188 float max_offset = root_max_scroll_offset.x() + (page_scale_factor - 1)
189 / page_scale_factor * layout_viewport_size.width();
190 float offset = (max_offset >= 1) ? root_scroll_offset.x() +
191 layout_viewport_position.x() : 0;
192 thumb_position = offset / max_offset * maximum_position;
193
194 // Thumb rect position is with respect to the layer, so the y-coordinate
195 // should be 0.
196 new_thumb_rect = gfx::Rect(thumb_position, 0, thumb_length, track_width);
197 }
198
199 gfx::Rect& thumb_rect = state_->thumb_rect();
200 scoped_ptr<ScopedResource>& thumb_texture = state_->thumb_texture();
201
202 bool thumb_size_not_changed = thumb_rect.size() == new_thumb_rect.size();
203 thumb_rect = new_thumb_rect;
204 if (thumb_size_not_changed && thumb_texture)
205 return;
206
207 // Does texture exist, if not, create it.
208 if (!thumb_texture)
209 thumb_texture = ScopedResource::create(resource_provider);
210
211 if (thumb_texture->size() != thumb_rect.size())
212 thumb_texture->Free();
213
214 if (!thumb_texture->id())
215 thumb_texture->Allocate(thumb_rect.size(), GL_RGBA,
216 ResourceProvider::TextureUsageAny);
217
218 // Paint canvas and upload to texture.
219 scoped_ptr<SkCanvas> canvas = make_scoped_ptr(
220 skia::CreateBitmapCanvas(thumb_rect.width(), thumb_rect.height(),
221 false /* opaque */));
222 canvas->clear(SkColorSetARGB(0, 0, 0, 0));
223 SkPaint paint;
224 // Below 255 refers to blue, not red, but we do this to avoid an
225 // explicit swizzle.
226 paint.setColor(SkColorSetARGB(128, 255, 0, 0));
227 SkScalar border = device_scale_factor;
228 SkScalar corner_radius = device_scale_factor * (track_width / 3);
229 DCHECK(corner_radius);
230 SkRect rect = SkRect::MakeXYWH(border, border,
231 thumb_rect.width() - 2 * border,
232 thumb_rect.height() - 2 * border);
233 canvas->drawRoundRect(rect, corner_radius, corner_radius, paint);
234
235 const SkBitmap* bitmap = &canvas->getDevice()->accessBitmap(false);
236 SkAutoLockPixels locker(*bitmap);
237 gfx::Rect layer_rect(gfx::Point(), thumb_rect.size());
238 DCHECK(bitmap->config() == SkBitmap::kARGB_8888_Config);
239 resource_provider->setPixels(thumb_texture->id(), static_cast<const uint8_t*>(
240 bitmap->getPixels()), layer_rect, layer_rect,
241 gfx::Vector2d());
242 }
243
244 void PinchZoomScrollbarLayerImpl::didLoseOutputSurface() {
245 state_->thumb_texture().reset(0);;
246 }
247
248 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698