• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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 "chrome/browser/extensions/extension_icon_manager.h"
6 
7 #include "base/logging.h"
8 #include "base/stl_util-inl.h"
9 #include "chrome/common/extensions/extension.h"
10 #include "chrome/common/extensions/extension_icon_set.h"
11 #include "chrome/common/extensions/extension_resource.h"
12 #include "grit/theme_resources.h"
13 #include "skia/ext/image_operations.h"
14 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/gfx/canvas_skia.h"
16 #include "ui/gfx/color_utils.h"
17 #include "ui/gfx/favicon_size.h"
18 #include "ui/gfx/size.h"
19 #include "ui/gfx/skbitmap_operations.h"
20 
21 namespace {
22 
23 // Helper function to create a new bitmap with |padding| amount of empty space
24 // around the original bitmap.
ApplyPadding(const SkBitmap & source,const gfx::Insets & padding)25 static SkBitmap ApplyPadding(const SkBitmap& source,
26                              const gfx::Insets& padding) {
27   scoped_ptr<gfx::CanvasSkia> result(
28       new gfx::CanvasSkia(source.width() + padding.width(),
29                           source.height() + padding.height(), false));
30   result->DrawBitmapInt(
31       source,
32       0, 0, source.width(), source.height(),
33       padding.left(), padding.top(), source.width(), source.height(),
34       false);
35   return result->ExtractBitmap();
36 }
37 
38 }  // namespace
39 
ExtensionIconManager()40 ExtensionIconManager::ExtensionIconManager()
41     : ALLOW_THIS_IN_INITIALIZER_LIST(image_tracker_(this)),
42       monochrome_(false) {
43 }
44 
~ExtensionIconManager()45 ExtensionIconManager::~ExtensionIconManager() {
46 }
47 
LoadIcon(const Extension * extension)48 void ExtensionIconManager::LoadIcon(const Extension* extension) {
49   ExtensionResource icon_resource = extension->GetIconResource(
50       Extension::EXTENSION_ICON_BITTY, ExtensionIconSet::MATCH_BIGGER);
51   if (!icon_resource.extension_root().empty()) {
52     // Insert into pending_icons_ first because LoadImage can call us back
53     // synchronously if the image is already cached.
54     pending_icons_.insert(extension->id());
55     image_tracker_.LoadImage(extension,
56                              icon_resource,
57                              gfx::Size(kFaviconSize, kFaviconSize),
58                              ImageLoadingTracker::CACHE);
59   }
60 }
61 
GetIcon(const std::string & extension_id)62 const SkBitmap& ExtensionIconManager::GetIcon(const std::string& extension_id) {
63   const SkBitmap* result = NULL;
64   if (ContainsKey(icons_, extension_id)) {
65     result = &icons_[extension_id];
66   } else {
67     EnsureDefaultIcon();
68     result = &default_icon_;
69   }
70   DCHECK(result);
71   DCHECK_EQ(kFaviconSize + padding_.width(), result->width());
72   DCHECK_EQ(kFaviconSize + padding_.height(), result->height());
73   return *result;
74 }
75 
RemoveIcon(const std::string & extension_id)76 void ExtensionIconManager::RemoveIcon(const std::string& extension_id) {
77   icons_.erase(extension_id);
78   pending_icons_.erase(extension_id);
79 }
80 
OnImageLoaded(SkBitmap * image,const ExtensionResource & resource,int index)81 void ExtensionIconManager::OnImageLoaded(SkBitmap* image,
82                                          const ExtensionResource& resource,
83                                          int index) {
84   if (!image)
85     return;
86 
87   const std::string extension_id = resource.extension_id();
88 
89   // We may have removed the icon while waiting for it to load. In that case,
90   // do nothing.
91   if (!ContainsKey(pending_icons_, extension_id))
92     return;
93 
94   pending_icons_.erase(extension_id);
95   icons_[extension_id] = ApplyTransforms(*image);
96 }
97 
EnsureDefaultIcon()98 void ExtensionIconManager::EnsureDefaultIcon() {
99   if (default_icon_.empty()) {
100     ResourceBundle& rb = ResourceBundle::GetSharedInstance();
101     SkBitmap* src = rb.GetBitmapNamed(IDR_EXTENSIONS_SECTION);
102     default_icon_ = ApplyTransforms(*src);
103   }
104 }
105 
ApplyTransforms(const SkBitmap & source)106 SkBitmap ExtensionIconManager::ApplyTransforms(const SkBitmap& source) {
107   SkBitmap result = source;
108 
109   if (result.width() != kFaviconSize || result.height() != kFaviconSize) {
110     result = skia::ImageOperations::Resize(
111         result, skia::ImageOperations::RESIZE_LANCZOS3,
112         kFaviconSize, kFaviconSize);
113   }
114 
115   if (monochrome_) {
116     color_utils::HSL shift = {-1, 0, 0.6};
117     result = SkBitmapOperations::CreateHSLShiftedBitmap(result, shift);
118   }
119 
120   if (!padding_.empty())
121     result = ApplyPadding(result, padding_);
122 
123   return result;
124 }
125