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

Side by Side Diff: chrome/common/extensions/extension_action.cc

Issue 10827191: Convert extension action icons code to use ImageSkia instead of SkBitmap (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 8 years, 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/common/extensions/extension_action.h" 5 #include "chrome/common/extensions/extension_action.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "chrome/common/badge_util.h" 10 #include "chrome/common/badge_util.h"
11 #include "googleurl/src/gurl.h" 11 #include "googleurl/src/gurl.h"
12 #include "grit/theme_resources.h" 12 #include "grit/theme_resources.h"
13 #include "grit/ui_resources.h" 13 #include "grit/ui_resources.h"
14 #include "third_party/skia/include/core/SkBitmap.h" 14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "third_party/skia/include/core/SkCanvas.h" 15 #include "third_party/skia/include/core/SkCanvas.h"
16 #include "third_party/skia/include/core/SkDevice.h" 16 #include "third_party/skia/include/core/SkDevice.h"
17 #include "third_party/skia/include/core/SkPaint.h" 17 #include "third_party/skia/include/core/SkPaint.h"
18 #include "third_party/skia/include/effects/SkGradientShader.h" 18 #include "third_party/skia/include/effects/SkGradientShader.h"
19 #include "ui/base/animation/animation_delegate.h" 19 #include "ui/base/animation/animation_delegate.h"
20 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/canvas.h" 21 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/color_utils.h" 22 #include "ui/gfx/color_utils.h"
23 #include "ui/gfx/image/image_skia.h"
24 #include "ui/gfx/image/image_skia_source.h"
23 #include "ui/gfx/rect.h" 25 #include "ui/gfx/rect.h"
24 #include "ui/gfx/image/image_skia_source.h" 26 #include "ui/gfx/image/image_skia_source.h"
25 #include "ui/gfx/skbitmap_operations.h" 27 #include "ui/gfx/skbitmap_operations.h"
26 28
27 namespace { 29 namespace {
28 30
29 // Different platforms need slightly different constants to look good. 31 // Different platforms need slightly different constants to look good.
30 #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) 32 #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)
31 const float kTextSize = 9.0; 33 const float kTextSize = 9.0;
32 const int kBottomMargin = 0; 34 const int kBottomMargin = 0;
(...skipping 16 matching lines...) Expand all
49 // The padding between the top of the badge and the top of the text. 51 // The padding between the top of the badge and the top of the text.
50 const int kTopTextPadding = -1; 52 const int kTopTextPadding = -1;
51 #endif 53 #endif
52 54
53 const int kBadgeHeight = 11; 55 const int kBadgeHeight = 11;
54 const int kMaxTextWidth = 23; 56 const int kMaxTextWidth = 23;
55 // The minimum width for center-aligning the badge. 57 // The minimum width for center-aligning the badge.
56 const int kCenterAlignThreshold = 20; 58 const int kCenterAlignThreshold = 20;
57 59
58 60
59 int Width(const gfx::Image& image) { 61 int Width(const gfx::ImageSkia& image) {
60 if (image.IsEmpty()) 62 return image.size().width();
61 return 0;
62 return image.ToSkBitmap()->width();
63 } 63 }
64 64
65 class GetAttentionImageSource : public gfx::ImageSkiaSource { 65 class GetAttentionImageSource : public gfx::ImageSkiaSource {
66 public: 66 public:
67 explicit GetAttentionImageSource(const gfx::Image& icon) 67 explicit GetAttentionImageSource(const gfx::ImageSkia& icon)
68 : icon_(*icon.ToImageSkia()) {} 68 : icon_(icon) {}
69 69
70 // gfx::ImageSkiaSource overrides: 70 // gfx::ImageSkiaSource overrides:
71 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) 71 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor)
72 OVERRIDE { 72 OVERRIDE {
73 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale_factor); 73 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale_factor);
74 color_utils::HSL shift = {-1, 0, 0.5}; 74 color_utils::HSL shift = {-1, 0, 0.5};
75 return gfx::ImageSkiaRep( 75 return gfx::ImageSkiaRep(
76 SkBitmapOperations::CreateHSLShiftedBitmap(icon_rep.sk_bitmap(), shift), 76 SkBitmapOperations::CreateHSLShiftedBitmap(icon_rep.sk_bitmap(), shift),
77 icon_rep.scale_factor()); 77 icon_rep.scale_factor());
78 } 78 }
(...skipping 29 matching lines...) Expand all
108 Done(); 108 Done();
109 } 109 }
110 110
111 void Done() { 111 void Done() {
112 delete this; 112 delete this;
113 } 113 }
114 114
115 IconAnimation animation_; 115 IconAnimation animation_;
116 }; 116 };
117 117
118 // Source for painting animated skia image.
119 class ExtensionAction::AnimatedIconImageSource : public gfx::ImageSkiaSource {
120 public:
121 AnimatedIconImageSource(const gfx::ImageSkia& image,
122 IconAnimationWrapper* animation)
123 : image_(image),
124 animation_(animation->AsWeakPtr()) {
125 }
126
127 private:
128 virtual ~AnimatedIconImageSource() {}
129
130 virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale) OVERRIDE {
131 gfx::ImageSkiaRep original_rep = image_.GetRepresentation(scale);
132 if (!animation_) {
133 return original_rep;
134 }
135
136 // Original representation's scale factor may be different from scale
137 // factor passed to this method. We want to use the former (since we are
138 // using bitmap for that scale).
139 return gfx::ImageSkiaRep(
140 animation_->animation()->Apply(original_rep.sk_bitmap()),
141 original_rep.scale_factor());
142 }
143
144 gfx::ImageSkia image_;
145 base::WeakPtr<IconAnimationWrapper> animation_;
146 };
147
148
118 const int ExtensionAction::kDefaultTabId = -1; 149 const int ExtensionAction::kDefaultTabId = -1;
119 150
120 ExtensionAction::IconAnimation::IconAnimation( 151 ExtensionAction::IconAnimation::IconAnimation(
121 ui::AnimationDelegate* delegate) 152 ui::AnimationDelegate* delegate)
122 // 100ms animation at 50fps (so 5 animation frames in total). 153 // 100ms animation at 50fps (so 5 animation frames in total).
123 : ui::LinearAnimation(100, 50, delegate) {} 154 : ui::LinearAnimation(100, 50, delegate) {}
124 155
125 ExtensionAction::IconAnimation::~IconAnimation() {} 156 ExtensionAction::IconAnimation::~IconAnimation() {}
126 157
127 const SkBitmap& ExtensionAction::IconAnimation::Apply( 158 const SkBitmap& ExtensionAction::IconAnimation::Apply(
pkotwicz 2012/08/07 22:31:22 Can we merge this logic into AnimatedIconSource. (
tbarzic 2012/08/08 02:09:29 added todo..
128 const SkBitmap& icon) const { 159 const SkBitmap& icon) const {
129 DCHECK_GT(icon.width(), 0); 160 DCHECK_GT(icon.width(), 0);
130 DCHECK_GT(icon.height(), 0); 161 DCHECK_GT(icon.height(), 0);
131 162
132 if (!device_.get() || 163 if (!device_.get() ||
133 (device_->width() != icon.width()) || 164 (device_->width() != icon.width()) ||
134 (device_->height() != icon.height())) { 165 (device_->height() != icon.height())) {
135 device_.reset(new SkDevice( 166 device_.reset(new SkDevice(
136 SkBitmap::kARGB_8888_Config, icon.width(), icon.height(), true)); 167 SkBitmap::kARGB_8888_Config, icon.width(), icon.height(), true));
137 } 168 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 241
211 bool ExtensionAction::HasPopup(int tab_id) const { 242 bool ExtensionAction::HasPopup(int tab_id) const {
212 return !GetPopupUrl(tab_id).is_empty(); 243 return !GetPopupUrl(tab_id).is_empty();
213 } 244 }
214 245
215 GURL ExtensionAction::GetPopupUrl(int tab_id) const { 246 GURL ExtensionAction::GetPopupUrl(int tab_id) const {
216 return GetValue(&popup_url_, tab_id); 247 return GetValue(&popup_url_, tab_id);
217 } 248 }
218 249
219 void ExtensionAction::CacheIcon(const std::string& path, 250 void ExtensionAction::CacheIcon(const std::string& path,
220 const gfx::Image& icon) { 251 const gfx::ImageSkia& icon) {
221 if (!icon.IsEmpty()) 252 if (!icon.empty())
222 path_to_icon_cache_.insert(std::make_pair(path, icon)); 253 path_to_icon_cache_.insert(std::make_pair(path, icon));
223 } 254 }
224 255
225 void ExtensionAction::SetIcon(int tab_id, const SkBitmap& bitmap) { 256 void ExtensionAction::SetIcon(int tab_id, const gfx::ImageSkia& image) {
226 SetValue(&icon_, tab_id, gfx::Image(bitmap)); 257 SetValue(&icon_, tab_id, image);
227 } 258 }
228 259
229 gfx::Image ExtensionAction::GetIcon(int tab_id) const { 260 gfx::ImageSkia ExtensionAction::GetIcon(int tab_id) const {
230 // Check if a specific icon is set for this tab. 261 // Check if a specific icon is set for this tab.
231 gfx::Image icon = GetValue(&icon_, tab_id); 262 gfx::ImageSkia icon = GetValue(&icon_, tab_id);
232 if (icon.IsEmpty()) { 263 if (icon.empty()) {
233 // Need to find an icon from a path. 264 // Need to find an icon from a path.
234 const std::string* path = NULL; 265 const std::string* path = NULL;
235 // Check if one of the elements of icon_path() was selected. 266 // Check if one of the elements of icon_path() was selected.
236 int icon_index = GetIconIndex(tab_id); 267 int icon_index = GetIconIndex(tab_id);
237 if (icon_index >= 0) { 268 if (icon_index >= 0) {
238 path = &icon_paths()->at(icon_index); 269 path = &icon_paths()->at(icon_index);
239 } else { 270 } else {
240 // Otherwise, use the default icon. 271 // Otherwise, use the default icon.
241 path = &default_icon_path(); 272 path = &default_icon_path();
242 } 273 }
243 274
244 std::map<std::string, gfx::Image>::const_iterator cached_icon = 275 std::map<std::string, gfx::ImageSkia>::const_iterator cached_icon =
245 path_to_icon_cache_.find(*path); 276 path_to_icon_cache_.find(*path);
246 if (cached_icon != path_to_icon_cache_.end()) { 277 if (cached_icon != path_to_icon_cache_.end()) {
247 icon = cached_icon->second; 278 icon = cached_icon->second;
248 } else { 279 } else {
249 icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( 280 icon = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
250 IDR_EXTENSIONS_FAVICON); 281 IDR_EXTENSIONS_FAVICON);
251 } 282 }
252 } 283 }
253 284
254 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION) { 285 if (GetValue(&appearance_, tab_id) == WANTS_ATTENTION)
255 icon = gfx::Image(gfx::ImageSkia(new GetAttentionImageSource(icon), 286 icon = gfx::ImageSkia(new GetAttentionImageSource(icon), icon.size());
256 icon.ToImageSkia()->size()));
257 }
258 287
259 return ApplyIconAnimation(tab_id, icon); 288 return ApplyIconAnimation(tab_id, icon);
260 } 289 }
261 290
262 void ExtensionAction::SetIconIndex(int tab_id, int index) { 291 void ExtensionAction::SetIconIndex(int tab_id, int index) {
263 if (static_cast<size_t>(index) >= icon_paths_.size()) { 292 if (static_cast<size_t>(index) >= icon_paths_.size()) {
264 NOTREACHED(); 293 NOTREACHED();
265 return; 294 return;
266 } 295 }
267 SetValue(&icon_index_, tab_id, index); 296 SetValue(&icon_index_, tab_id, index);
(...skipping 24 matching lines...) Expand all
292 badge_text_.erase(tab_id); 321 badge_text_.erase(tab_id);
293 badge_text_color_.erase(tab_id); 322 badge_text_color_.erase(tab_id);
294 badge_background_color_.erase(tab_id); 323 badge_background_color_.erase(tab_id);
295 appearance_.erase(tab_id); 324 appearance_.erase(tab_id);
296 icon_animation_.erase(tab_id); 325 icon_animation_.erase(tab_id);
297 } 326 }
298 327
299 void ExtensionAction::PaintBadge(gfx::Canvas* canvas, 328 void ExtensionAction::PaintBadge(gfx::Canvas* canvas,
300 const gfx::Rect& bounds, 329 const gfx::Rect& bounds,
301 int tab_id) { 330 int tab_id) {
302 std::string text = GetBadgeText(tab_id); 331 ExtensionAction::DoPaintBadge(
332 canvas,
333 bounds,
334 GetBadgeText(tab_id),
335 GetBadgeTextColor(tab_id),
336 GetBadgeBackgroundColor(tab_id),
337 Width(GetValue(&icon_, tab_id)));
338 }
339
340 // static
341 void ExtensionAction::DoPaintBadge(gfx::Canvas* canvas,
342 const gfx::Rect& bounds,
343 const std::string& text,
344 const SkColor& text_color_in,
345 const SkColor& background_color_in,
346 int icon_width) {
303 if (text.empty()) 347 if (text.empty())
304 return; 348 return;
305 349
306 SkColor text_color = GetBadgeTextColor(tab_id); 350 SkColor text_color = (SkColorGetA(text_color_in) == 0x00) ?
307 SkColor background_color = GetBadgeBackgroundColor(tab_id); 351 SK_ColorWHITE : text_color_in;
308 352
309 if (SkColorGetA(text_color) == 0x00) 353 SkColor background_color = (SkColorGetA(background_color_in) == 0x00) ?
310 text_color = SK_ColorWHITE; 354 SkColorSetARGB(255, 218, 0, 24) : background_color_in;
311
312 if (SkColorGetA(background_color) == 0x00)
313 background_color = SkColorSetARGB(255, 218, 0, 24); // Default badge color.
314 355
315 canvas->Save(); 356 canvas->Save();
316 357
317 SkPaint* text_paint = badge_util::GetBadgeTextPaintSingleton(); 358 SkPaint* text_paint = badge_util::GetBadgeTextPaintSingleton();
318 text_paint->setTextSize(SkFloatToScalar(kTextSize)); 359 text_paint->setTextSize(SkFloatToScalar(kTextSize));
319 text_paint->setColor(text_color); 360 text_paint->setColor(text_color);
320 361
321 // Calculate text width. We clamp it to a max size. 362 // Calculate text width. We clamp it to a max size.
322 SkScalar text_width = text_paint->measureText(text.c_str(), text.size()); 363 SkScalar text_width_sk = text_paint->measureText(text.c_str(), text.size());
323 text_width = SkIntToScalar( 364 int text_width = std::min(kMaxTextWidth, SkScalarFloor(text_width_sk));
324 std::min(kMaxTextWidth, SkScalarFloor(text_width)));
325 365
326 // Calculate badge size. It is clamped to a min width just because it looks 366 // Calculate badge size. It is clamped to a min width just because it looks
327 // silly if it is too skinny. 367 // silly if it is too skinny.
328 int badge_width = SkScalarFloor(text_width) + kPadding * 2; 368 int badge_width = text_width + kPadding * 2;
329 int icon_width = Width(GetValue(&icon_, tab_id));
330 // Force the pixel width of badge to be either odd (if the icon width is odd) 369 // Force the pixel width of badge to be either odd (if the icon width is odd)
331 // or even otherwise. If there is a mismatch you get http://crbug.com/26400. 370 // or even otherwise. If there is a mismatch you get http://crbug.com/26400.
332 if (icon_width != 0 && (badge_width % 2 != icon_width % 2)) 371 if (icon_width != 0 && (badge_width % 2 != icon_width % 2))
333 badge_width += 1; 372 badge_width += 1;
334 badge_width = std::max(kBadgeHeight, badge_width); 373 badge_width = std::max(kBadgeHeight, badge_width);
335 374
336 // Paint the badge background color in the right location. It is usually 375 // Paint the badge background color in the right location. It is usually
337 // right-aligned, but it can also be center-aligned if it is large. 376 // right-aligned, but it can also be center-aligned if it is large.
338 SkRect rect; 377 int rect_height = kBadgeHeight;
339 rect.fBottom = SkIntToScalar(bounds.bottom() - kBottomMargin); 378 int rect_y = bounds.bottom() - kBottomMargin - kBadgeHeight;
340 rect.fTop = rect.fBottom - SkIntToScalar(kBadgeHeight); 379 int rect_width = badge_width;
341 if (badge_width >= kCenterAlignThreshold) { 380 int rect_x = (badge_width >= kCenterAlignThreshold) ?
342 rect.fLeft = SkIntToScalar( 381 (bounds.x() + bounds.width()) / 2 - badge_width / 2 :
343 SkScalarFloor(SkIntToScalar(bounds.x()) + 382 bounds.right() - badge_width;
344 SkIntToScalar(bounds.width()) / 2 - 383 gfx::Rect rect(rect_x, rect_y, rect_width, rect_height);
345 SkIntToScalar(badge_width) / 2));
346 rect.fRight = rect.fLeft + SkIntToScalar(badge_width);
347 } else {
348 rect.fRight = SkIntToScalar(bounds.right());
349 rect.fLeft = rect.fRight - badge_width;
350 }
351 384
352 SkPaint rect_paint; 385 SkPaint rect_paint;
353 rect_paint.setStyle(SkPaint::kFill_Style); 386 rect_paint.setStyle(SkPaint::kFill_Style);
354 rect_paint.setAntiAlias(true); 387 rect_paint.setAntiAlias(true);
355 rect_paint.setColor(background_color); 388 rect_paint.setColor(background_color);
356 canvas->sk_canvas()->drawRoundRect(rect, SkIntToScalar(2), 389 canvas->DrawRoundRect(rect, 2, rect_paint);
357 SkIntToScalar(2), rect_paint);
358 390
359 // Overlay the gradient. It is stretchy, so we do this in three parts. 391 // Overlay the gradient. It is stretchy, so we do this in three parts.
360 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 392 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
361 SkBitmap* gradient_left = rb.GetBitmapNamed(IDR_BROWSER_ACTION_BADGE_LEFT); 393 gfx::ImageSkia* gradient_left = rb.GetImageSkiaNamed(
362 SkBitmap* gradient_right = rb.GetBitmapNamed(IDR_BROWSER_ACTION_BADGE_RIGHT); 394 IDR_BROWSER_ACTION_BADGE_LEFT);
363 SkBitmap* gradient_center = rb.GetBitmapNamed( 395 gfx::ImageSkia* gradient_right = rb.GetImageSkiaNamed(
396 IDR_BROWSER_ACTION_BADGE_RIGHT);
397 gfx::ImageSkia* gradient_center = rb.GetImageSkiaNamed(
364 IDR_BROWSER_ACTION_BADGE_CENTER); 398 IDR_BROWSER_ACTION_BADGE_CENTER);
365 399
366 canvas->sk_canvas()->drawBitmap(*gradient_left, rect.fLeft, rect.fTop); 400 canvas->DrawImageInt(*gradient_left, rect.x(), rect.y());
367 canvas->TileImageInt(*gradient_center, 401 canvas->TileImageInt(*gradient_center,
368 SkScalarFloor(rect.fLeft) + gradient_left->width(), 402 rect.x() + gradient_left->width(),
369 SkScalarFloor(rect.fTop), 403 rect.y(),
370 SkScalarFloor(rect.width()) - gradient_left->width() - 404 rect.width() - gradient_left->width() - gradient_right->width(),
371 gradient_right->width(), 405 rect.height());
372 SkScalarFloor(rect.height())); 406 canvas->DrawImageInt(*gradient_right,
373 canvas->sk_canvas()->drawBitmap(*gradient_right, 407 rect.right() - gradient_right->width(), rect.y());
374 rect.fRight - SkIntToScalar(gradient_right->width()), rect.fTop);
375 408
376 // Finally, draw the text centered within the badge. We set a clip in case the 409 // Finally, draw the text centered within the badge. We set a clip in case the
377 // text was too large. 410 // text was too large.
378 rect.fLeft += kPadding; 411 rect.Inset(kPadding, 0);
379 rect.fRight -= kPadding; 412 canvas->ClipRect(rect);
380 canvas->sk_canvas()->clipRect(rect);
381 canvas->sk_canvas()->drawText(text.c_str(), text.size(), 413 canvas->sk_canvas()->drawText(text.c_str(), text.size(),
382 rect.fLeft + (rect.width() - text_width) / 2, 414 rect.x() + (rect.width() - text_width) / 2,
383 rect.fTop + kTextSize + kTopTextPadding, 415 rect.y() + kTextSize + kTopTextPadding,
384 *text_paint); 416 *text_paint);
385 canvas->Restore(); 417 canvas->Restore();
386 } 418 }
387 419
388 ExtensionAction::IconAnimationWrapper* ExtensionAction::GetIconAnimationWrapper( 420 ExtensionAction::IconAnimationWrapper* ExtensionAction::GetIconAnimationWrapper(
389 int tab_id) const { 421 int tab_id) const {
390 std::map<int, base::WeakPtr<IconAnimationWrapper> >::iterator it = 422 std::map<int, base::WeakPtr<IconAnimationWrapper> >::iterator it =
391 icon_animation_.find(tab_id); 423 icon_animation_.find(tab_id);
392 if (it == icon_animation_.end()) 424 if (it == icon_animation_.end())
393 return NULL; 425 return NULL;
(...skipping 14 matching lines...) Expand all
408 return NULL; 440 return NULL;
409 } 441 }
410 442
411 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation( 443 base::WeakPtr<ExtensionAction::IconAnimation> ExtensionAction::GetIconAnimation(
412 int tab_id) const { 444 int tab_id) const {
413 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id); 445 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id);
414 return wrapper ? wrapper->animation()->AsWeakPtr() 446 return wrapper ? wrapper->animation()->AsWeakPtr()
415 : base::WeakPtr<IconAnimation>(); 447 : base::WeakPtr<IconAnimation>();
416 } 448 }
417 449
418 gfx::Image ExtensionAction::ApplyIconAnimation(int tab_id, 450 gfx::ImageSkia ExtensionAction::ApplyIconAnimation(
419 const gfx::Image& orig) const { 451 int tab_id,
420 IconAnimationWrapper* wrapper = GetIconAnimationWrapper(tab_id); 452 const gfx::ImageSkia& icon) const {
421 if (wrapper == NULL) 453 IconAnimationWrapper* animation_wrapper = GetIconAnimationWrapper(tab_id);
422 return orig; 454 if (animation_wrapper == NULL)
423 return gfx::Image(wrapper->animation()->Apply(*orig.ToSkBitmap())); 455 return icon;
456
457 return gfx::ImageSkia(new AnimatedIconImageSource(icon, animation_wrapper),
458 icon.size());
424 } 459 }
425 460
426 void ExtensionAction::RunIconAnimation(int tab_id) { 461 void ExtensionAction::RunIconAnimation(int tab_id) {
427 IconAnimationWrapper* icon_animation = 462 IconAnimationWrapper* icon_animation =
428 new IconAnimationWrapper(); 463 new IconAnimationWrapper();
429 icon_animation_[tab_id] = icon_animation->AsWeakPtr(); 464 icon_animation_[tab_id] = icon_animation->AsWeakPtr();
430 icon_animation->animation()->Start(); 465 icon_animation->animation()->Start();
431 } 466 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698