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

Side by Side Diff: chrome/browser/chromeos/status/network_menu_icon.cc

Issue 10704199: Implement remaining SkBitmapOperations as ImageSkiaOperations (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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/browser/chromeos/status/network_menu_icon.h" 5 #include "chrome/browser/chromeos/status/network_menu_icon.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <map> 9 #include <map>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/chromeos/accessibility/accessibility_util.h" 13 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
14 #include "chrome/browser/chromeos/cros/cros_library.h" 14 #include "chrome/browser/chromeos/cros/cros_library.h"
15 #include "grit/generated_resources.h" 15 #include "grit/generated_resources.h"
16 #include "grit/theme_resources.h" 16 #include "grit/theme_resources.h"
17 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/canvas.h" 19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/image/image_skia_operations.h"
20 #include "ui/gfx/image/image_skia_source.h" 21 #include "ui/gfx/image/image_skia_source.h"
21 #include "ui/gfx/skbitmap_operations.h"
22 22
23 using std::max; 23 using std::max;
24 using std::min; 24 using std::min;
25 25
26 namespace chromeos { 26 namespace chromeos {
27 27
28 namespace { 28 namespace {
29 29
30 // Amount to fade icons while connecting. 30 // Amount to fade icons while connecting.
31 const double kConnectingImageAlpha = 0.5; 31 const double kConnectingImageAlpha = 0.5;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 break; 151 break;
152 case NETWORK_TECHNOLOGY_UNKNOWN: 152 case NETWORK_TECHNOLOGY_UNKNOWN:
153 break; 153 break;
154 } 154 }
155 if (id == kUnknownBadgeType) 155 if (id == kUnknownBadgeType)
156 return NULL; 156 return NULL;
157 else 157 else
158 return ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); 158 return ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id);
159 } 159 }
160 160
161 const SkBitmap GetEmptyBitmapOfSameSize(const gfx::ImageSkiaRep& reference) { 161 class EmptyImageSource: public gfx::ImageSkiaSource {
162 typedef std::pair<int, int> SizeKey;
163 typedef std::map<SizeKey, SkBitmap> SizeBitmapMap;
164 static SizeBitmapMap* empty_bitmaps_ = new SizeBitmapMap;
165
166 SizeKey key(reference.pixel_width(), reference.pixel_height());
167
168 SizeBitmapMap::iterator iter = empty_bitmaps_->find(key);
169 if (iter != empty_bitmaps_->end())
170 return iter->second;
171
172 SkBitmap empty;
173 empty.setConfig(SkBitmap::kARGB_8888_Config, key.first, key.second);
174 empty.allocPixels();
175 empty.eraseARGB(0, 0, 0, 0);
176 (*empty_bitmaps_)[key] = empty;
177 return empty;
178 }
179
180 class FadedImageSource : public gfx::ImageSkiaSource {
181 public: 162 public:
182 FadedImageSource(const gfx::ImageSkia& source, double alpha) 163 EmptyImageSource(const gfx::Size& size)
183 : source_(source), 164 : size_(size) {
184 alpha_(alpha) {
185 } 165 }
186 virtual ~FadedImageSource() {}
187 166
188 virtual gfx::ImageSkiaRep GetImageForScale( 167 virtual gfx::ImageSkiaRep GetImageForScale(
189 ui::ScaleFactor scale_factor) OVERRIDE { 168 ui::ScaleFactor scale_factor) OVERRIDE {
190 gfx::ImageSkiaRep image_rep = source_.GetRepresentation(scale_factor); 169 SkBitmap empty;
191 const SkBitmap empty_bitmap = GetEmptyBitmapOfSameSize(image_rep); 170 empty.setConfig(SkBitmap::kARGB_8888_Config, size_.width(),
192 SkBitmap faded_bitmap = SkBitmapOperations::CreateBlendedBitmap( 171 size_.height());
193 empty_bitmap, image_rep.sk_bitmap(), alpha_); 172 empty.allocPixels();
194 return gfx::ImageSkiaRep(faded_bitmap, image_rep.scale_factor()); 173 empty.eraseARGB(0, 0, 0, 0);
oshima 2012/07/13 16:54:55 can we cache this? I think it'd save more than cac
174 return gfx::ImageSkiaRep(empty, scale_factor);
195 } 175 }
176 private:
177 const gfx::Size size_;
196 178
197 private: 179 DISALLOW_COPY_AND_ASSIGN(EmptyImageSource);
198 const gfx::ImageSkia source_;
199 const float alpha_;
200
201 DISALLOW_COPY_AND_ASSIGN(FadedImageSource);
202 }; 180 };
203 181
204 // This defines how we assemble a network icon. 182 // This defines how we assemble a network icon.
205 class NetworkIconImageSource : public gfx::ImageSkiaSource { 183 class NetworkIconImageSource : public gfx::ImageSkiaSource {
206 public: 184 public:
207 NetworkIconImageSource(const gfx::ImageSkia& icon, 185 NetworkIconImageSource(const gfx::ImageSkia& icon,
208 const gfx::ImageSkia* top_left_badge, 186 const gfx::ImageSkia* top_left_badge,
209 const gfx::ImageSkia* top_right_badge, 187 const gfx::ImageSkia* top_right_badge,
210 const gfx::ImageSkia* bottom_left_badge, 188 const gfx::ImageSkia* bottom_left_badge,
211 const gfx::ImageSkia* bottom_right_badge) 189 const gfx::ImageSkia* bottom_right_badge)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 private: 223 private:
246 const gfx::ImageSkia icon_; 224 const gfx::ImageSkia icon_;
247 const gfx::ImageSkia *top_left_badge_; 225 const gfx::ImageSkia *top_left_badge_;
248 const gfx::ImageSkia *top_right_badge_; 226 const gfx::ImageSkia *top_right_badge_;
249 const gfx::ImageSkia *bottom_left_badge_; 227 const gfx::ImageSkia *bottom_left_badge_;
250 const gfx::ImageSkia *bottom_right_badge_; 228 const gfx::ImageSkia *bottom_right_badge_;
251 229
252 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); 230 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource);
253 }; 231 };
254 232
255 // This defines how we assemble a network menu icon.
256 class NetworkMenuIconSource : public gfx::ImageSkiaSource {
257 public:
258 NetworkMenuIconSource(NetworkMenuIcon::ImageType type,
259 int index,
260 NetworkMenuIcon::ResourceColorTheme color)
261 : type_(type),
262 index_(index),
263 color_(color) {
264 }
265 virtual ~NetworkMenuIconSource() {}
266
267 virtual gfx::ImageSkiaRep GetImageForScale(
268 ui::ScaleFactor scale_factor) OVERRIDE {
269 int width, height;
270 gfx::ImageSkia* images;
271 if (type_ == NetworkMenuIcon::ARCS) {
272 if (index_ >= kNumArcsImages)
273 return gfx::ImageSkiaRep();
274 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
275 color_ == NetworkMenuIcon::COLOR_DARK ?
276 IDR_STATUSBAR_NETWORK_ARCS_DARK : IDR_STATUSBAR_NETWORK_ARCS_LIGHT);
277 width = images->width();
278 height = images->height() / kNumArcsImages;
279 } else {
280 if (index_ >= kNumBarsImages)
281 return gfx::ImageSkiaRep();
282
283 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
284 color_ == NetworkMenuIcon::COLOR_DARK ?
285 IDR_STATUSBAR_NETWORK_BARS_DARK : IDR_STATUSBAR_NETWORK_BARS_LIGHT);
286 width = images->width();
287 height = images->height() / kNumBarsImages;
288 }
289 gfx::ImageSkiaRep image_rep = images->GetRepresentation(scale_factor);
290
291 float scale = ui::GetScaleFactorScale(image_rep.scale_factor());
292 height *= scale;
293 width *= scale;
294
295 SkIRect subset = SkIRect::MakeXYWH(0, index_ * height, width, height);
296
297 SkBitmap dst_bitmap;
298 image_rep.sk_bitmap().extractSubset(&dst_bitmap, subset);
299 return gfx::ImageSkiaRep(dst_bitmap, image_rep.scale_factor());
300 }
301
302 gfx::Size size() const {
303 // NeworkMenuIcons all have the same size in DIP for arc/bars.
304 if (type_ == NetworkMenuIcon::ARCS) {
305 gfx::Size size = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
306 IDR_STATUSBAR_NETWORK_ARCS_DARK)->size();
307 return gfx::Size(size.width(), size.height() / kNumArcsImages);
308 } else {
309 gfx::Size size = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
310 IDR_STATUSBAR_NETWORK_BARS_DARK)->size();
311 return gfx::Size(size.width(), size.height() / kNumBarsImages);
312 }
313 }
314
315 private:
316 const NetworkMenuIcon::ImageType type_;
317 const int index_;
318 const NetworkMenuIcon::ResourceColorTheme color_;
319
320 DISALLOW_COPY_AND_ASSIGN(NetworkMenuIconSource);
321 };
322
323 gfx::ImageSkia CreateVpnImage() { 233 gfx::ImageSkia CreateVpnImage() {
324 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 234 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
325 const gfx::ImageSkia* ethernet_icon = rb.GetImageSkiaNamed(IDR_STATUSBAR_VPN); 235 const gfx::ImageSkia* ethernet_icon = rb.GetImageSkiaNamed(IDR_STATUSBAR_VPN);
326 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId); 236 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId);
327 return NetworkMenuIcon::GenerateImageFromComponents( 237 return NetworkMenuIcon::GenerateImageFromComponents(
328 *ethernet_icon, NULL, NULL, vpn_badge, NULL); 238 *ethernet_icon, NULL, NULL, vpn_badge, NULL);
329 } 239 }
330 240
241 gfx::ImageSkia CreateEmptyImage(const gfx::Size& size) {
oshima 2012/07/13 16:54:55 GetEmptyImage is probably better. Is this only pla
pkotwicz 2012/07/15 03:36:48 I haven't found a place which does something simil
242 typedef std::pair<int, int> SizeKey;
243 typedef std::map<SizeKey, gfx::ImageSkia> SizeImageMap;
244 static SizeImageMap* empty_images = new SizeImageMap;
245
246 SizeKey key(size.width(), size.height());
247 SizeImageMap::iterator iter = empty_images->find(key);
248
249 if (iter != empty_images->end())
250 return iter->second;
251
252 gfx::ImageSkia empty = gfx::ImageSkia(new EmptyImageSource(size), size);
253 (*empty_images)[key] = empty;
254 return empty;
255 }
256
331 } // namespace 257 } // namespace
332 258
333 //////////////////////////////////////////////////////////////////////////////// 259 ////////////////////////////////////////////////////////////////////////////////
334 // NetworkIcon 260 // NetworkIcon
335 // TODO(stevenjb): Separate class implementation from the definition. 261 // TODO(stevenjb): Separate class implementation from the definition.
336 262
337 // Sets up and generates an ImageSkia for a Network icon. 263 // Sets up and generates an ImageSkia for a Network icon.
338 class NetworkIcon { 264 class NetworkIcon {
339 public: 265 public:
340 // Default constructor is used by the status bar icon (NetworkMenuIcon). 266 // Default constructor is used by the status bar icon (NetworkMenuIcon).
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 icon_->UpdateIcon(network); 752 icon_->UpdateIcon(network);
827 // Overlay the VPN badge if connecting to a VPN. 753 // Overlay the VPN badge if connecting to a VPN.
828 if (network->type() != TYPE_VPN && cros->virtual_network()) { 754 if (network->type() != TYPE_VPN && cros->virtual_network()) {
829 if (cros->virtual_network()->connecting()) { 755 if (cros->virtual_network()->connecting()) {
830 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId); 756 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId);
831 const double animation = GetAnimation(); 757 const double animation = GetAnimation();
832 animating = true; 758 animating = true;
833 // Even though this is the only place we use vpn_connecting_badge_, 759 // Even though this is the only place we use vpn_connecting_badge_,
834 // it is important that this is a member variable since we set a 760 // it is important that this is a member variable since we set a
835 // pointer to it and access that pointer in icon_->GenerateImage(). 761 // pointer to it and access that pointer in icon_->GenerateImage().
836 vpn_connecting_badge_ = gfx::ImageSkia( 762 vpn_connecting_badge_ = gfx::ImageSkiaOperations::CreateBlendedImage(
837 new FadedImageSource(*vpn_badge, animation), vpn_badge->size()); 763 CreateEmptyImage(vpn_badge->size()), *vpn_badge, animation);
838 icon_->set_bottom_left_badge(&vpn_connecting_badge_); 764 icon_->set_bottom_left_badge(&vpn_connecting_badge_);
839 } 765 }
840 } 766 }
841 if (!animating) 767 if (!animating)
842 animation_connecting_.Stop(); 768 animation_connecting_.Stop();
843 769
844 // Set the text to display. 770 // Set the text to display.
845 if (network->type() == TYPE_ETHERNET) { 771 if (network->type() == TYPE_ETHERNET) {
846 if (mode_ == MENU_MODE) { 772 if (mode_ == MENU_MODE) {
847 text_ = l10n_util::GetStringFUTF16( 773 text_ = l10n_util::GetStringFUTF16(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 top_left_badge, 829 top_left_badge,
904 top_right_badge, 830 top_right_badge,
905 bottom_left_badge, 831 bottom_left_badge,
906 bottom_right_badge), 832 bottom_right_badge),
907 icon.size()); 833 icon.size());
908 } 834 }
909 835
910 // We blend connecting icons with a black image to generate a faded icon. 836 // We blend connecting icons with a black image to generate a faded icon.
911 const gfx::ImageSkia NetworkMenuIcon::GenerateConnectingImage( 837 const gfx::ImageSkia NetworkMenuIcon::GenerateConnectingImage(
912 const gfx::ImageSkia& source) { 838 const gfx::ImageSkia& source) {
913 return gfx::ImageSkia(new FadedImageSource(source, kConnectingImageAlpha), 839 return gfx::ImageSkiaOperations::CreateBlendedImage(
914 source.size()); 840 CreateEmptyImage(source.size()), source, kConnectingImageAlpha);
915 } 841 }
916 842
917 // Generates and caches an icon image for a network's current state. 843 // Generates and caches an icon image for a network's current state.
918 const gfx::ImageSkia NetworkMenuIcon::GetImage(const Network* network, 844 const gfx::ImageSkia NetworkMenuIcon::GetImage(const Network* network,
919 ResourceColorTheme color) { 845 ResourceColorTheme color) {
920 DCHECK(network); 846 DCHECK(network);
921 // Maintain a static (global) icon map. Note: Icons are never destroyed; 847 // Maintain a static (global) icon map. Note: Icons are never destroyed;
922 // it is assumed that a finite and reasonable number of network icons will be 848 // it is assumed that a finite and reasonable number of network icons will be
923 // created during a session. 849 // created during a session.
924 850
(...skipping 23 matching lines...) Expand all
948 874
949 // Returns an icon for a disconnected VPN. 875 // Returns an icon for a disconnected VPN.
950 const gfx::ImageSkia NetworkMenuIcon::GetVpnImage() { 876 const gfx::ImageSkia NetworkMenuIcon::GetVpnImage() {
951 static const gfx::ImageSkia *vpn_image = new gfx::ImageSkia(CreateVpnImage()); 877 static const gfx::ImageSkia *vpn_image = new gfx::ImageSkia(CreateVpnImage());
952 return *vpn_image; 878 return *vpn_image;
953 } 879 }
954 880
955 const gfx::ImageSkia NetworkMenuIcon::GetImage(ImageType type, 881 const gfx::ImageSkia NetworkMenuIcon::GetImage(ImageType type,
956 int index, 882 int index,
957 ResourceColorTheme color) { 883 ResourceColorTheme color) {
958 NetworkMenuIconSource* source = new NetworkMenuIconSource(type, index, color); 884 int width, height;
959 return gfx::ImageSkia(source, source->size()); 885 gfx::ImageSkia* images;
886 if (type == NetworkMenuIcon::ARCS) {
887 if (index >= kNumArcsImages)
888 return gfx::ImageSkia();
889 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
890 color == NetworkMenuIcon::COLOR_DARK ?
891 IDR_STATUSBAR_NETWORK_ARCS_DARK : IDR_STATUSBAR_NETWORK_ARCS_LIGHT);
892 width = images->width();
893 height = images->height() / kNumArcsImages;
894 } else {
895 if (index >= kNumBarsImages)
896 return gfx::ImageSkia();
897
898 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
899 color == NetworkMenuIcon::COLOR_DARK ?
900 IDR_STATUSBAR_NETWORK_BARS_DARK : IDR_STATUSBAR_NETWORK_BARS_LIGHT);
901 width = images->width();
902 height = images->height() / kNumBarsImages;
903 }
904 return gfx::ImageSkiaOperations::ExtractSubset(*images,
905 gfx::Rect(0, index * height, width, height));
960 } 906 }
961 907
962 const gfx::ImageSkia NetworkMenuIcon::GetDisconnectedImage( 908 const gfx::ImageSkia NetworkMenuIcon::GetDisconnectedImage(
963 ImageType type, 909 ImageType type,
964 ResourceColorTheme color) { 910 ResourceColorTheme color) {
965 return GetImage(type, 0, color); 911 return GetImage(type, 0, color);
966 } 912 }
967 913
968 const gfx::ImageSkia NetworkMenuIcon::GetConnectedImage(ImageType type, 914 const gfx::ImageSkia NetworkMenuIcon::GetConnectedImage(ImageType type,
969 ResourceColorTheme color) { 915 ResourceColorTheme color) {
970 return GetImage(type, NumImages(type) - 1, color); 916 return GetImage(type, NumImages(type) - 1, color);
971 } 917 }
972 918
973 int NetworkMenuIcon::NumImages(ImageType type) { 919 int NetworkMenuIcon::NumImages(ImageType type) {
974 return (type == ARCS) ? kNumArcsImages : kNumBarsImages; 920 return (type == ARCS) ? kNumArcsImages : kNumBarsImages;
975 } 921 }
976 922
977 } // chromeos 923 } // chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698