diff options
author | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-23 20:35:07 +0000 |
---|---|---|
committer | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-23 20:35:07 +0000 |
commit | 474a0984f645ad944d37e3dc14c52b72fb6a74ad (patch) | |
tree | 07ccbe68dd58150fe2876820654284421cd592fd | |
parent | 8fedfee482c62619a504a59316fb07a3b0f1995a (diff) | |
download | chromium_src-474a0984f645ad944d37e3dc14c52b72fb6a74ad.zip chromium_src-474a0984f645ad944d37e3dc14c52b72fb6a74ad.tar.gz chromium_src-474a0984f645ad944d37e3dc14c52b72fb6a74ad.tar.bz2 |
Implement remaining SkBitmapOperations as ImageSkiaOperations
Bug=None
Test=Compiles, code looks nicer
R=oshima,sky
TBR=sadrul
Review URL: https://chromiumcodereview.appspot.com/10704199
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147925 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/system/web_notification/web_notification_tray.cc | 23 | ||||
-rw-r--r-- | ash/wm/workspace/frame_maximize_button.cc | 5 | ||||
-rw-r--r-- | ash/wm/workspace/frame_maximize_button.h | 3 | ||||
-rw-r--r-- | chrome/browser/chromeos/status/network_menu_icon.cc | 133 | ||||
-rw-r--r-- | ui/gfx/image/image_skia.cc | 29 | ||||
-rw-r--r-- | ui/gfx/image/image_skia.h | 6 | ||||
-rw-r--r-- | ui/gfx/image/image_skia_operations.cc | 94 | ||||
-rw-r--r-- | ui/gfx/image/image_skia_operations.h | 21 | ||||
-rw-r--r-- | ui/views/controls/button/image_button.cc | 67 | ||||
-rw-r--r-- | ui/views/controls/button/image_button.h | 16 | ||||
-rw-r--r-- | ui/views/controls/button/image_button_unittest.cc | 22 |
11 files changed, 200 insertions, 219 deletions
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc index ac0afdc..72b8984 100644 --- a/ash/system/web_notification/web_notification_tray.cc +++ b/ash/system/web_notification/web_notification_tray.cc @@ -16,6 +16,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/simple_menu_model.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image_skia_operations.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/button/menu_button_listener.h" @@ -60,21 +61,19 @@ const int kToggleExtensionCommand = 1; const int kShowSettingsCommand = 2; // The image has three icons: 1 notifiaction, 2 notifications, and 3+. -SkBitmap GetNotificationImage(int notification_count) { - SkBitmap image; - gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed( - IDR_AURA_UBER_TRAY_WEB_NOTIFICATON); +gfx::ImageSkia GetNotificationImage(int notification_count) { + const gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance(). + GetImageSkiaNamed(IDR_AURA_UBER_TRAY_WEB_NOTIFICATON); int image_index = notification_count - 1; image_index = std::max(0, std::min(image_index, 2)); // The original width of the image looks too big, so we need to inset // it somewhat. - SkIRect region = SkIRect::MakeXYWH( - kNotificationImageIconInset, image_index * kNotificationImageIconHeight, - kNotificationImageIconWidth - 2 * kNotificationImageIconInset, - kNotificationImageIconHeight); - - all.ToSkBitmap()->extractSubset(&image, region); - return image; + gfx::Rect region( + kNotificationImageIconInset, + image_index * kNotificationImageIconHeight, + kNotificationImageIconWidth - 2 * kNotificationImageIconInset, + kNotificationImageIconHeight); + return gfx::ImageSkiaOperations::ExtractSubset(*image, region); } } // namespace @@ -878,7 +877,7 @@ void WebNotificationTray::UpdateIcon() { status_area_widget_->login_status() == user::LOGGED_IN_LOCKED) { SetVisible(false); } else { - icon_->SetImage(gfx::ImageSkia(GetNotificationImage(count))); + icon_->SetImage(GetNotificationImage(count)); SetVisible(true); } PreferredSizeChanged(); diff --git a/ash/wm/workspace/frame_maximize_button.cc b/ash/wm/workspace/frame_maximize_button.cc index 386a2ac..213f4d2 100644 --- a/ash/wm/workspace/frame_maximize_button.cc +++ b/ash/wm/workspace/frame_maximize_button.cc @@ -180,8 +180,7 @@ ui::GestureStatus FrameMaximizeButton::OnGestureEvent( return ImageButton::OnGestureEvent(event); } -gfx::ImageSkia FrameMaximizeButton::GetImageToPaint( - ui::ScaleFactor scale_factor) { +gfx::ImageSkia FrameMaximizeButton::GetImageToPaint() { if (is_snap_enabled_) { int id = 0; if (frame_->GetWidget()->IsMaximized()) { @@ -226,7 +225,7 @@ gfx::ImageSkia FrameMaximizeButton::GetImageToPaint( return *ResourceBundle::GetSharedInstance().GetImageNamed(id).ToImageSkia(); } // Hot and pressed states handled by regular ImageButton. - return ImageButton::GetImageToPaint(scale_factor); + return ImageButton::GetImageToPaint(); } void FrameMaximizeButton::ProcessStartEvent(const views::LocatedEvent& event) { diff --git a/ash/wm/workspace/frame_maximize_button.h b/ash/wm/workspace/frame_maximize_button.h index 7cc7b7b..0124c2f 100644 --- a/ash/wm/workspace/frame_maximize_button.h +++ b/ash/wm/workspace/frame_maximize_button.h @@ -40,8 +40,7 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton { protected: // ImageButton overrides: - virtual gfx::ImageSkia GetImageToPaint( - ui::ScaleFactor scale_factor) OVERRIDE; + virtual gfx::ImageSkia GetImageToPaint() OVERRIDE; private: class EscapeEventFilter; diff --git a/chrome/browser/chromeos/status/network_menu_icon.cc b/chrome/browser/chromeos/status/network_menu_icon.cc index f2db0dc..d546d8a 100644 --- a/chrome/browser/chromeos/status/network_menu_icon.cc +++ b/chrome/browser/chromeos/status/network_menu_icon.cc @@ -17,8 +17,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/image/image_skia_source.h" -#include "ui/gfx/skbitmap_operations.h" using std::max; using std::min; @@ -158,12 +158,12 @@ const gfx::ImageSkia* BadgeForNetworkTechnology( return ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); } -const SkBitmap GetEmptyBitmapOfSameSize(const gfx::ImageSkiaRep& reference) { +const SkBitmap GetEmptyBitmap(const gfx::Size pixel_size) { typedef std::pair<int, int> SizeKey; typedef std::map<SizeKey, SkBitmap> SizeBitmapMap; static SizeBitmapMap* empty_bitmaps_ = new SizeBitmapMap; - SizeKey key(reference.pixel_width(), reference.pixel_height()); + SizeKey key(pixel_size.width(), pixel_size.height()); SizeBitmapMap::iterator iter = empty_bitmaps_->find(key); if (iter != empty_bitmaps_->end()) @@ -177,28 +177,22 @@ const SkBitmap GetEmptyBitmapOfSameSize(const gfx::ImageSkiaRep& reference) { return empty; } -class FadedImageSource : public gfx::ImageSkiaSource { +class EmptyImageSource: public gfx::ImageSkiaSource { public: - FadedImageSource(const gfx::ImageSkia& source, double alpha) - : source_(source), - alpha_(alpha) { + EmptyImageSource(const gfx::Size& size) + : size_(size) { } - virtual ~FadedImageSource() {} virtual gfx::ImageSkiaRep GetImageForScale( ui::ScaleFactor scale_factor) OVERRIDE { - gfx::ImageSkiaRep image_rep = source_.GetRepresentation(scale_factor); - const SkBitmap empty_bitmap = GetEmptyBitmapOfSameSize(image_rep); - SkBitmap faded_bitmap = SkBitmapOperations::CreateBlendedBitmap( - empty_bitmap, image_rep.sk_bitmap(), alpha_); - return gfx::ImageSkiaRep(faded_bitmap, image_rep.scale_factor()); + gfx::Size pixel_size = size_.Scale(ui::GetScaleFactorScale(scale_factor)); + SkBitmap empty_bitmap = GetEmptyBitmap(pixel_size); + return gfx::ImageSkiaRep(empty_bitmap, scale_factor); } - private: - const gfx::ImageSkia source_; - const float alpha_; + const gfx::Size size_; - DISALLOW_COPY_AND_ASSIGN(FadedImageSource); + DISALLOW_COPY_AND_ASSIGN(EmptyImageSource); }; // This defines how we assemble a network icon. @@ -252,75 +246,6 @@ class NetworkIconImageSource : public gfx::ImageSkiaSource { DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); }; -// This defines how we assemble a network menu icon. -class NetworkMenuIconSource : public gfx::ImageSkiaSource { - public: - NetworkMenuIconSource(NetworkMenuIcon::ImageType type, - int index, - NetworkMenuIcon::ResourceColorTheme color) - : type_(type), - index_(index), - color_(color) { - } - virtual ~NetworkMenuIconSource() {} - - virtual gfx::ImageSkiaRep GetImageForScale( - ui::ScaleFactor scale_factor) OVERRIDE { - int width, height; - gfx::ImageSkia* images; - if (type_ == NetworkMenuIcon::ARCS) { - if (index_ >= kNumArcsImages) - return gfx::ImageSkiaRep(); - images = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - color_ == NetworkMenuIcon::COLOR_DARK ? - IDR_STATUSBAR_NETWORK_ARCS_DARK : IDR_STATUSBAR_NETWORK_ARCS_LIGHT); - width = images->width(); - height = images->height() / kNumArcsImages; - } else { - if (index_ >= kNumBarsImages) - return gfx::ImageSkiaRep(); - - images = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - color_ == NetworkMenuIcon::COLOR_DARK ? - IDR_STATUSBAR_NETWORK_BARS_DARK : IDR_STATUSBAR_NETWORK_BARS_LIGHT); - width = images->width(); - height = images->height() / kNumBarsImages; - } - gfx::ImageSkiaRep image_rep = images->GetRepresentation(scale_factor); - - float scale = ui::GetScaleFactorScale(image_rep.scale_factor()); - height *= scale; - width *= scale; - - SkIRect subset = SkIRect::MakeXYWH(0, index_ * height, width, height); - - SkBitmap dst_bitmap; - image_rep.sk_bitmap().extractSubset(&dst_bitmap, subset); - return gfx::ImageSkiaRep(dst_bitmap, image_rep.scale_factor()); - } - - gfx::Size size() const { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - // NeworkMenuIcons all have the same size in DIP for arc/bars. - if (type_ == NetworkMenuIcon::ARCS) { - gfx::Size size = rb.GetImageSkiaNamed( - IDR_STATUSBAR_NETWORK_ARCS_DARK)->size(); - return gfx::Size(size.width(), size.height() / kNumArcsImages); - } else { - gfx::Size size = rb.GetImageSkiaNamed( - IDR_STATUSBAR_NETWORK_BARS_DARK)->size(); - return gfx::Size(size.width(), size.height() / kNumBarsImages); - } - } - - private: - const NetworkMenuIcon::ImageType type_; - const int index_; - const NetworkMenuIcon::ResourceColorTheme color_; - - DISALLOW_COPY_AND_ASSIGN(NetworkMenuIconSource); -}; - gfx::ImageSkia CreateVpnImage() { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); const gfx::ImageSkia* ethernet_icon = rb.GetImageSkiaNamed(IDR_STATUSBAR_VPN); @@ -329,6 +254,10 @@ gfx::ImageSkia CreateVpnImage() { *ethernet_icon, NULL, NULL, vpn_badge, NULL); } +gfx::ImageSkia GetEmptyImage(const gfx::Size& size) { + return gfx::ImageSkia(new EmptyImageSource(size), size); +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -853,8 +782,8 @@ void NetworkMenuIcon::SetActiveNetworkIconAndText(const Network* network) { // Even though this is the only place we use vpn_connecting_badge_, // it is important that this is a member variable since we set a // pointer to it and access that pointer in icon_->GenerateImage(). - vpn_connecting_badge_ = gfx::ImageSkia( - new FadedImageSource(*vpn_badge, animation), vpn_badge->size()); + vpn_connecting_badge_ = gfx::ImageSkiaOperations::CreateBlendedImage( + GetEmptyImage(vpn_badge->size()), *vpn_badge, animation); icon_->set_bottom_left_badge(&vpn_connecting_badge_); } } @@ -930,8 +859,8 @@ const gfx::ImageSkia NetworkMenuIcon::GenerateImageFromComponents( // We blend connecting icons with a black image to generate a faded icon. const gfx::ImageSkia NetworkMenuIcon::GenerateConnectingImage( const gfx::ImageSkia& source) { - return gfx::ImageSkia(new FadedImageSource(source, kConnectingImageAlpha), - source.size()); + return gfx::ImageSkiaOperations::CreateBlendedImage( + GetEmptyImage(source.size()), source, kConnectingImageAlpha); } // Generates and caches an icon image for a network's current state. @@ -975,8 +904,28 @@ const gfx::ImageSkia NetworkMenuIcon::GetVpnImage() { const gfx::ImageSkia NetworkMenuIcon::GetImage(ImageType type, int index, ResourceColorTheme color) { - NetworkMenuIconSource* source = new NetworkMenuIconSource(type, index, color); - return gfx::ImageSkia(source, source->size()); + int width, height = 0; + gfx::ImageSkia* images = NULL; + if (type == NetworkMenuIcon::ARCS) { + if (index >= kNumArcsImages) + return gfx::ImageSkia(); + images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + color == NetworkMenuIcon::COLOR_DARK ? + IDR_STATUSBAR_NETWORK_ARCS_DARK : IDR_STATUSBAR_NETWORK_ARCS_LIGHT); + width = images->width(); + height = images->height() / kNumArcsImages; + } else { + if (index >= kNumBarsImages) + return gfx::ImageSkia(); + + images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + color == NetworkMenuIcon::COLOR_DARK ? + IDR_STATUSBAR_NETWORK_BARS_DARK : IDR_STATUSBAR_NETWORK_BARS_LIGHT); + width = images->width(); + height = images->height() / kNumBarsImages; + } + return gfx::ImageSkiaOperations::ExtractSubset(*images, + gfx::Rect(0, index * height, width, height)); } const gfx::ImageSkia NetworkMenuIcon::GetDisconnectedImage( diff --git a/ui/gfx/image/image_skia.cc b/ui/gfx/image/image_skia.cc index ec11272..4210484 100644 --- a/ui/gfx/image/image_skia.cc +++ b/ui/gfx/image/image_skia.cc @@ -10,7 +10,9 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/image/image_skia_source.h" +#include "ui/gfx/rect.h" #include "ui/gfx/size.h" #include "ui/gfx/skia_util.h" @@ -265,30 +267,9 @@ int ImageSkia::height() const { } bool ImageSkia::extractSubset(ImageSkia* dst, const SkIRect& subset) const { - if (isNull()) - return false; - ImageSkia image; - ImageSkiaReps& image_reps = storage_->image_reps(); - for (ImageSkiaReps::iterator it = image_reps.begin(); - it != image_reps.end(); ++it) { - const ImageSkiaRep& image_rep = *it; - float dip_scale = image_rep.GetScale(); - // Rounding boundary in case of a non-integer scale factor. - int x = static_cast<int>(subset.left() * dip_scale + 0.5); - int y = static_cast<int>(subset.top() * dip_scale + 0.5); - int w = static_cast<int>(subset.width() * dip_scale + 0.5); - int h = static_cast<int>(subset.height() * dip_scale + 0.5); - SkBitmap dst_bitmap; - SkIRect scaled_subset = SkIRect::MakeXYWH(x, y, w, h); - if (image_rep.sk_bitmap().extractSubset(&dst_bitmap, scaled_subset)) - image.AddRepresentation(ImageSkiaRep(dst_bitmap, - image_rep.scale_factor())); - } - if (image.empty()) - return false; - - *dst = image; - return true; + gfx::Rect rect(subset.x(), subset.y(), subset.width(), subset.height()); + *dst = ImageSkiaOperations::ExtractSubset(*this, rect); + return (!dst->isNull()); } std::vector<ImageSkiaRep> ImageSkia::image_reps() const { diff --git a/ui/gfx/image/image_skia.h b/ui/gfx/image/image_skia.h index 08725be..fffae7a 100644 --- a/ui/gfx/image/image_skia.h +++ b/ui/gfx/image/image_skia.h @@ -104,10 +104,8 @@ class UI_EXPORT ImageSkia { gfx::Size size() const; // Wrapper function for SkBitmap::extractBitmap. - // Operates on each stored image rep. Note that it may not have - // all image reps for supported scale factors. - // TODO(oshima|pkotwicz): Investigate if this can be eliminated - // after ImageSkiaSource conversion. + // Deprecated, use ImageSkiaOperations::ExtractSubset instead. + // TODO(pkotwicz): Remove this function. bool extractSubset(ImageSkia* dst, const SkIRect& subset) const; // Returns pointer to 1x bitmap contained by this object. If there is no 1x diff --git a/ui/gfx/image/image_skia_operations.cc b/ui/gfx/image/image_skia_operations.cc index 8a3aa12..547584f5 100644 --- a/ui/gfx/image/image_skia_operations.cc +++ b/ui/gfx/image/image_skia_operations.cc @@ -68,6 +68,9 @@ class BlendingImageSource : public gfx::ImageSkiaSource { alpha_(alpha) { } + virtual ~BlendingImageSource() { + } + // gfx::ImageSkiaSource overrides: virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { ImageSkiaRep first_rep = first_.GetRepresentation(scale_factor); @@ -93,6 +96,9 @@ class MaskedImageSource : public gfx::ImageSkiaSource { alpha_(alpha) { } + virtual ~MaskedImageSource() { + } + // gfx::ImageSkiaSource overrides: virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { ImageSkiaRep rgb_rep = rgb_.GetRepresentation(scale_factor); @@ -122,6 +128,9 @@ class TiledImageSource : public gfx::ImageSkiaSource { dst_h_(dst_h) { } + virtual ~TiledImageSource() { + } + // gfx::ImageSkiaSource overrides: virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { ImageSkiaRep source_rep = source_.GetRepresentation(scale_factor); @@ -143,6 +152,72 @@ class TiledImageSource : public gfx::ImageSkiaSource { DISALLOW_COPY_AND_ASSIGN(TiledImageSource); }; +// ImageSkiaSource which uses SkBitmapOperations::CreateButtonBackground +// to generate image reps for the target image. +class ButtonImageSource: public gfx::ImageSkiaSource { + public: + ButtonImageSource(SkColor color, + const ImageSkia& image, + const ImageSkia& mask) + : color_(color), + image_(image), + mask_(mask) { + } + + virtual ~ButtonImageSource() { + } + + // gfx::ImageSkiaSource overrides: + virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { + ImageSkiaRep image_rep = image_.GetRepresentation(scale_factor); + ImageSkiaRep mask_rep = mask_.GetRepresentation(scale_factor); + MatchScale(&image_rep, &mask_rep); + return ImageSkiaRep( + SkBitmapOperations::CreateButtonBackground(color_, + image_rep.sk_bitmap(), mask_rep.sk_bitmap()), + image_rep.scale_factor()); + } + + private: + const SkColor color_; + const ImageSkia image_; + const ImageSkia mask_; + + DISALLOW_COPY_AND_ASSIGN(ButtonImageSource); +}; + +// ImageSkiaSource which uses SkBitmap::extractSubset to generate image reps +// for the target image. +class ExtractSubsetImageSource: public gfx::ImageSkiaSource { + public: + ExtractSubsetImageSource(const gfx::ImageSkia& image, + const gfx::Rect& subset_bounds) + : image_(image), + subset_bounds_(subset_bounds) { + } + + ~ExtractSubsetImageSource() { + } + + // gfx::ImageSkiaSource overrides: + virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { + ImageSkiaRep image_rep = image_.GetRepresentation(scale_factor); + SkIRect subset_bounds_in_pixel = RectToSkIRect(subset_bounds_.Scale( + ui::GetScaleFactorScale(image_rep.scale_factor()))); + SkBitmap dst; + bool success = image_rep.sk_bitmap().extractSubset(&dst, + subset_bounds_in_pixel); + DCHECK(success); + return gfx::ImageSkiaRep(dst, image_rep.scale_factor()); + } + + private: + const gfx::ImageSkia image_; + const gfx::Rect subset_bounds_; + + DISALLOW_COPY_AND_ASSIGN(ExtractSubsetImageSource); +}; + // ResizeSource resizes relevant image reps in |source| to |target_dip_size| // for requested scale factors. class ResizeSource : public ImageSkiaSource { @@ -235,6 +310,25 @@ ImageSkia ImageSkiaOperations::CreateTiledImage(const ImageSkia& source, } // static +ImageSkia ImageSkiaOperations::CreateButtonBackground(SkColor color, + const ImageSkia& image, + const ImageSkia& mask) { + return ImageSkia(new ButtonImageSource(color, image, mask), mask.size()); +} + +// static +ImageSkia ImageSkiaOperations::ExtractSubset(const ImageSkia& image, + const Rect& subset_bounds) { + gfx::Rect clipped_bounds = subset_bounds.Intersect(gfx::Rect(image.size())); + if (image.isNull() || clipped_bounds.IsEmpty()) { + return ImageSkia(); + } + + return ImageSkia(new ExtractSubsetImageSource(image, clipped_bounds), + clipped_bounds.size()); +} + +// static ImageSkia ImageSkiaOperations::CreateResizedImage(const ImageSkia& source, const Size& target_dip_size) { return ImageSkia(new ResizeSource(source, target_dip_size), target_dip_size); diff --git a/ui/gfx/image/image_skia_operations.h b/ui/gfx/image/image_skia_operations.h index 1e6a52a..993655c 100644 --- a/ui/gfx/image/image_skia_operations.h +++ b/ui/gfx/image/image_skia_operations.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_GFX_IMAGE_IMAGE_SKIA_OPERATIONS_H_ -#define UI_GFX_IMAGE_IMAGE_SKIA_OPERATIONS_H_ +#ifndef UI_GFX_IMAGE_SKIA_OPERATIONS_H_ +#define UI_GFX_IMAGE_SKIA_OPERATIONS_H_ #include "base/gtest_prod_util.h" #include "ui/base/ui_export.h" @@ -11,6 +11,7 @@ namespace gfx { class ImageSkia; +class Rect; class Size; class UI_EXPORT ImageSkiaOperations { @@ -35,6 +36,20 @@ class UI_EXPORT ImageSkiaOperations { int src_x, int src_y, int dst_w, int dst_h); + // Creates a button background image by compositing the color and image + // together, then applying the mask. This is a highly specialized composite + // operation that is the equivalent of drawing a background in |color|, + // tiling |image| over the top, and then masking the result out with |mask|. + // The images must use kARGB_8888_Config config. + static ImageSkia CreateButtonBackground(SkColor color, + const gfx::ImageSkia& image, + const gfx::ImageSkia& mask); + + // Returns an image which is a subset of |image| with bounds |subset_bounds|. + // The |image| cannot use kA1_Config config. + static ImageSkia ExtractSubset(const gfx::ImageSkia& image, + const gfx::Rect& subset_bounds); + // Creates an image by resizing |source| to given |target_dip_size|. static ImageSkia CreateResizedImage(const ImageSkia& source, const Size& target_dip_size); @@ -47,6 +62,6 @@ class UI_EXPORT ImageSkiaOperations { ImageSkiaOperations(); // Class for scoping only. }; -} +} // namespace gfx #endif // UI_GFX_IMAGE_IMAGE_SKIA_OPERATIONS_H_ diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc index a1b05c8..1640f99 100644 --- a/ui/views/controls/button/image_button.cc +++ b/ui/views/controls/button/image_button.cc @@ -7,8 +7,7 @@ #include "base/utf_string_conversions.h" #include "ui/base/animation/throb_animation.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/screen.h" -#include "ui/gfx/skbitmap_operations.h" +#include "ui/gfx/image/image_skia_operations.h" #include "ui/views/widget/widget.h" namespace views { @@ -41,10 +40,13 @@ void ImageButton::SetImage(ButtonState state, const gfx::ImageSkia* image) { void ImageButton::SetBackground(SkColor color, const gfx::ImageSkia* image, const gfx::ImageSkia* mask) { - background_image_.src_color_ = color; - background_image_.src_image_ = image ? *image : gfx::ImageSkia(); - background_image_.src_mask_ = mask ? *mask : gfx::ImageSkia(); - background_image_.result_ = gfx::ImageSkia(); + if (image == NULL || mask == NULL) { + background_image_ = gfx::ImageSkia(); + return; + } + + background_image_ = gfx::ImageSkiaOperations::CreateButtonBackground(color, + *image, *mask); } void ImageButton::SetOverlayImage(const gfx::ImageSkia* image) { @@ -75,8 +77,7 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) { // Call the base class first to paint any background/borders. View::OnPaint(canvas); - ui::ScaleFactor current_device_scale_factor = canvas->scale_factor(); - gfx::ImageSkia img = GetImageToPaint(current_device_scale_factor); + gfx::ImageSkia img = GetImageToPaint(); if (!img.isNull()) { int x = 0, y = 0; @@ -91,12 +92,8 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) { else if (v_alignment_ == ALIGN_BOTTOM) y = height() - img.height(); - if (!background_image_.result_.HasRepresentation( - current_device_scale_factor)) { - UpdateButtonBackground(current_device_scale_factor); - } - if (!background_image_.result_.empty()) - canvas->DrawImageInt(background_image_.result_, x, y); + if (!background_image_.isNull()) + canvas->DrawImageInt(background_image_, x, y); canvas->DrawImageInt(img, x, y); @@ -109,21 +106,12 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) { //////////////////////////////////////////////////////////////////////////////// // ImageButton, protected: -gfx::ImageSkia ImageButton::GetImageToPaint(ui::ScaleFactor scale_factor) { +gfx::ImageSkia ImageButton::GetImageToPaint() { gfx::ImageSkia img; if (!images_[BS_HOT].isNull() && hover_animation_->is_animating()) { - gfx::ImageSkiaRep normal_image_rep = images_[BS_NORMAL].GetRepresentation( - scale_factor); - gfx::ImageSkiaRep hot_image_rep = images_[BS_HOT].GetRepresentation( - scale_factor); - DCHECK_EQ(normal_image_rep.scale_factor(), hot_image_rep.scale_factor()); - SkBitmap blended_bitmap = SkBitmapOperations::CreateBlendedBitmap( - normal_image_rep.sk_bitmap(), - hot_image_rep.sk_bitmap(), - hover_animation_->GetCurrentValue()); - img = gfx::ImageSkia(gfx::ImageSkiaRep(blended_bitmap, - normal_image_rep.scale_factor())); + img = gfx::ImageSkiaOperations::CreateBlendedImage(images_[BS_NORMAL], + images_[BS_HOT], hover_animation_->GetCurrentValue()); } else { img = images_[state_]; } @@ -131,24 +119,6 @@ gfx::ImageSkia ImageButton::GetImageToPaint(ui::ScaleFactor scale_factor) { return !img.isNull() ? img : images_[BS_NORMAL]; } -void ImageButton::UpdateButtonBackground(ui::ScaleFactor scale_factor) { - gfx::ImageSkiaRep image_rep = - background_image_.src_image_.GetRepresentation(scale_factor); - gfx::ImageSkiaRep mask_image_rep = - background_image_.src_mask_.GetRepresentation(scale_factor); - if (image_rep.is_null() || mask_image_rep.is_null() || - background_image_.result_.HasRepresentation(image_rep.scale_factor())) { - return; - } - DCHECK_EQ(image_rep.scale_factor(), mask_image_rep.scale_factor()); - SkBitmap result = SkBitmapOperations::CreateButtonBackground( - background_image_.src_color_, - image_rep.sk_bitmap(), - mask_image_rep.sk_bitmap()); - background_image_.result_.AddRepresentation(gfx::ImageSkiaRep( - result, image_rep.scale_factor())); -} - //////////////////////////////////////////////////////////////////////////////// // ToggleImageButton, public: @@ -215,13 +185,4 @@ bool ToggleImageButton::GetTooltipText(const gfx::Point& p, return true; } -/////////////////////////////////////////////////////////////////////////////// -// struct BackgroundImageGenerationInfo -ImageButton::BackgroundImageGenerationInfo::BackgroundImageGenerationInfo() - : src_color_(0) { -} - -ImageButton::BackgroundImageGenerationInfo::~BackgroundImageGenerationInfo() { -} - } // namespace views diff --git a/ui/views/controls/button/image_button.h b/ui/views/controls/button/image_button.h index 4ec203b..215a9ac 100644 --- a/ui/views/controls/button/image_button.h +++ b/ui/views/controls/button/image_button.h @@ -64,9 +64,7 @@ class VIEWS_EXPORT ImageButton : public CustomButton { protected: // Returns the image to paint. This is invoked from paint and returns a value // from images. - // |scale_factor| is the scale factor at which the view is painted and the - // scale factor which should be used when mutating ImageSkias. - virtual gfx::ImageSkia GetImageToPaint(ui::ScaleFactor scale_factor); + virtual gfx::ImageSkia GetImageToPaint(); // Updates button background for |scale_factor|. void UpdateButtonBackground(ui::ScaleFactor scale_factor); @@ -74,17 +72,7 @@ class VIEWS_EXPORT ImageButton : public CustomButton { // The images used to render the different states of this button. gfx::ImageSkia images_[BS_COUNT]; - // Information necessary to generate background image. - struct BackgroundImageGenerationInfo { - BackgroundImageGenerationInfo(); - ~BackgroundImageGenerationInfo(); - - SkColor src_color_; - gfx::ImageSkia src_image_; - gfx::ImageSkia src_mask_; - gfx::ImageSkia result_; - }; - BackgroundImageGenerationInfo background_image_; + gfx::ImageSkia background_image_; // Image to draw on top of normal / hot / pushed image. Usually empty. gfx::ImageSkia overlay_image_; diff --git a/ui/views/controls/button/image_button_unittest.cc b/ui/views/controls/button/image_button_unittest.cc index 617a855..d95d79b 100644 --- a/ui/views/controls/button/image_button_unittest.cc +++ b/ui/views/controls/button/image_button_unittest.cc @@ -25,10 +25,8 @@ typedef ViewsTestBase ImageButtonTest; TEST_F(ImageButtonTest, Basics) { ImageButton button(NULL); - ui::ScaleFactor kRequestedScaleFactor = ui::SCALE_FACTOR_100P; - // Our image to paint starts empty. - EXPECT_TRUE(button.GetImageToPaint(kRequestedScaleFactor).empty()); + EXPECT_TRUE(button.GetImageToPaint().empty()); // Without a theme, buttons are 16x14 by default. EXPECT_EQ("16x14", button.GetPreferredSize().ToString()); @@ -42,9 +40,9 @@ TEST_F(ImageButtonTest, Basics) { button.SetImage(CustomButton::BS_NORMAL, &normal_image); // Image uses normal image for painting. - EXPECT_FALSE(button.GetImageToPaint(kRequestedScaleFactor).empty()); - EXPECT_EQ(10, button.GetImageToPaint(kRequestedScaleFactor).width()); - EXPECT_EQ(20, button.GetImageToPaint(kRequestedScaleFactor).height()); + EXPECT_FALSE(button.GetImageToPaint().empty()); + EXPECT_EQ(10, button.GetImageToPaint().width()); + EXPECT_EQ(20, button.GetImageToPaint().height()); // Preferred size is the normal button size. EXPECT_EQ("10x20", button.GetPreferredSize().ToString()); @@ -58,9 +56,9 @@ TEST_F(ImageButtonTest, Basics) { EXPECT_EQ("10x20", button.GetPreferredSize().ToString()); // We're still painting the normal image. - EXPECT_FALSE(button.GetImageToPaint(kRequestedScaleFactor).empty()); - EXPECT_EQ(10, button.GetImageToPaint(kRequestedScaleFactor).width()); - EXPECT_EQ(20, button.GetImageToPaint(kRequestedScaleFactor).height()); + EXPECT_FALSE(button.GetImageToPaint().empty()); + EXPECT_EQ(10, button.GetImageToPaint().width()); + EXPECT_EQ(20, button.GetImageToPaint().height()); // Set an overlay image. gfx::ImageSkia overlay_image = CreateTestImage(12, 22); @@ -73,9 +71,9 @@ TEST_F(ImageButtonTest, Basics) { EXPECT_EQ("10x20", button.GetPreferredSize().ToString()); // We're still painting the normal image. - EXPECT_FALSE(button.GetImageToPaint(kRequestedScaleFactor).empty()); - EXPECT_EQ(10, button.GetImageToPaint(kRequestedScaleFactor).width()); - EXPECT_EQ(20, button.GetImageToPaint(kRequestedScaleFactor).height()); + EXPECT_FALSE(button.GetImageToPaint().empty()); + EXPECT_EQ(10, button.GetImageToPaint().width()); + EXPECT_EQ(20, button.GetImageToPaint().height()); // Reset the overlay image. button.SetOverlayImage(NULL); |