summaryrefslogtreecommitdiffstats
path: root/ui/views
diff options
context:
space:
mode:
authorpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 00:21:45 +0000
committerpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-20 00:21:45 +0000
commitdad4661819c280d4468548864442face8082b0b2 (patch)
tree627e91e922b678d227f1fe40ec131be295db59f7 /ui/views
parent5951c851f2b1024645553a5657330c4005a5e3e3 (diff)
downloadchromium_src-dad4661819c280d4468548864442face8082b0b2.zip
chromium_src-dad4661819c280d4468548864442face8082b0b2.tar.gz
chromium_src-dad4661819c280d4468548864442face8082b0b2.tar.bz2
Make ImageButton and NetworkMenuIcon work in high DPI
Test=Manual Bug=None Testing steps 1) Run chromium using --force-device-scale-factor=2 --highlight-missing-2x-resources --load-2x-resources 2) Ensure that the hot image is not pixelated Review URL: https://chromiumcodereview.appspot.com/10546160 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143092 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views')
-rw-r--r--ui/views/controls/button/image_button.cc68
-rw-r--r--ui/views/controls/button/image_button.h25
-rw-r--r--ui/views/controls/button/image_button_unittest.cc22
3 files changed, 89 insertions, 26 deletions
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc
index a9d15fc..383cafd 100644
--- a/ui/views/controls/button/image_button.cc
+++ b/ui/views/controls/button/image_button.cc
@@ -7,7 +7,9 @@
#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/views/widget/widget.h"
namespace views {
@@ -39,13 +41,10 @@ void ImageButton::SetImage(ButtonState state, const gfx::ImageSkia* image) {
void ImageButton::SetBackground(SkColor color,
const gfx::ImageSkia* image,
const gfx::ImageSkia* mask) {
- if (!image || !mask) {
- background_image_ = gfx::ImageSkia();
- return;
- }
-
- background_image_ =
- SkBitmapOperations::CreateButtonBackground(color, *image, *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();
}
void ImageButton::SetOverlayImage(const gfx::ImageSkia* image) {
@@ -76,7 +75,8 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) {
// Call the base class first to paint any background/borders.
View::OnPaint(canvas);
- gfx::ImageSkia img = GetImageToPaint();
+ float current_device_scale = GetCurrentDeviceScale();
+ gfx::ImageSkia img = GetImageToPaint(current_device_scale);
if (!img.isNull()) {
int x = 0, y = 0;
@@ -91,8 +91,10 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) {
else if (v_alignment_ == ALIGN_BOTTOM)
y = height() - img.height();
- if (!background_image_.empty())
- canvas->DrawImageInt(background_image_, x, y);
+ if (!background_image_.result_.HasBitmapForScale(current_device_scale))
+ UpdateButtonBackground(current_device_scale);
+ if (!background_image_.result_.empty())
+ canvas->DrawImageInt(background_image_.result_, x, y);
canvas->DrawImageInt(img, x, y);
@@ -105,12 +107,26 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) {
////////////////////////////////////////////////////////////////////////////////
// ImageButton, protected:
-gfx::ImageSkia ImageButton::GetImageToPaint() {
+float ImageButton::GetCurrentDeviceScale() {
+ gfx::Display display = gfx::Screen::GetDisplayNearestWindow(
+ GetWidget() ? GetWidget()->GetNativeView() : NULL);
+ return display.device_scale_factor();
+}
+
+gfx::ImageSkia ImageButton::GetImageToPaint(float scale) {
gfx::ImageSkia img;
if (!images_[BS_HOT].isNull() && hover_animation_->is_animating()) {
- img = SkBitmapOperations::CreateBlendedBitmap(images_[BS_NORMAL],
- images_[BS_HOT], hover_animation_->GetCurrentValue());
+ float normal_bitmap_scale;
+ float hot_bitmap_scale;
+ SkBitmap normal_bitmap = images_[BS_NORMAL].GetBitmapForScale(
+ scale, &normal_bitmap_scale);
+ SkBitmap hot_bitmap = images_[BS_HOT].GetBitmapForScale(scale,
+ &hot_bitmap_scale);
+ DCHECK_EQ(normal_bitmap_scale, hot_bitmap_scale);
+ SkBitmap blended_bitmap = SkBitmapOperations::CreateBlendedBitmap(
+ normal_bitmap, hot_bitmap, hover_animation_->GetCurrentValue());
+ img = gfx::ImageSkia(blended_bitmap, normal_bitmap_scale);
} else {
img = images_[state_];
}
@@ -118,6 +134,23 @@ gfx::ImageSkia ImageButton::GetImageToPaint() {
return !img.isNull() ? img : images_[BS_NORMAL];
}
+void ImageButton::UpdateButtonBackground(float scale) {
+ float bitmap_scale;
+ float mask_scale;
+ SkBitmap bitmap = background_image_.src_image_.GetBitmapForScale(
+ scale, &bitmap_scale);
+ SkBitmap mask_bitmap = background_image_.src_mask_.GetBitmapForScale(
+ scale, &mask_scale);
+ if (bitmap.isNull() || mask_bitmap.isNull() ||
+ background_image_.result_.HasBitmapForScale(bitmap_scale)) {
+ return;
+ }
+ DCHECK_EQ(bitmap_scale, mask_scale);
+ SkBitmap result = SkBitmapOperations::CreateButtonBackground(
+ background_image_.src_color_, bitmap, mask_bitmap);
+ background_image_.result_.AddBitmapForScale(result, bitmap_scale);
+}
+
////////////////////////////////////////////////////////////////////////////////
// ToggleImageButton, public:
@@ -184,4 +217,13 @@ 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 b267e3c..49f44b8 100644
--- a/ui/views/controls/button/image_button.h
+++ b/ui/views/controls/button/image_button.h
@@ -7,6 +7,7 @@
#pragma once
#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/controls/button/custom_button.h"
@@ -62,15 +63,33 @@ class VIEWS_EXPORT ImageButton : public CustomButton {
}
protected:
+ // Returns the current device scale of the view.
+ // TODO(pkotwicz): Remove this once scale factor can be queried from canvas.
+ float GetCurrentDeviceScale();
+
// Returns the image to paint. This is invoked from paint and returns a value
// from images.
- virtual gfx::ImageSkia GetImageToPaint();
+ // |scale| is the scale at which the view is painted and the scale
+ // which should be used when mutating ImageSkias.
+ virtual gfx::ImageSkia GetImageToPaint(float scale);
+
+ // Updates button background for |scale|.
+ void UpdateButtonBackground(float scale);
// The images used to render the different states of this button.
gfx::ImageSkia images_[BS_COUNT];
- // The background image.
- gfx::ImageSkia background_image_;
+ // 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_;
// 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 4e6c5b2..8f5ea5f 100644
--- a/ui/views/controls/button/image_button_unittest.cc
+++ b/ui/views/controls/button/image_button_unittest.cc
@@ -24,8 +24,10 @@ typedef ViewsTestBase ImageButtonTest;
TEST_F(ImageButtonTest, Basics) {
ImageButton button(NULL);
+ float kRequestedScale = 1.0f;
+
// Our image to paint starts empty.
- EXPECT_TRUE(button.GetImageToPaint().empty());
+ EXPECT_TRUE(button.GetImageToPaint(kRequestedScale).empty());
// Without a theme, buttons are 16x14 by default.
EXPECT_EQ("16x14", button.GetPreferredSize().ToString());
@@ -39,9 +41,9 @@ TEST_F(ImageButtonTest, Basics) {
button.SetImage(CustomButton::BS_NORMAL, &normal_image);
// Image uses normal image for painting.
- EXPECT_FALSE(button.GetImageToPaint().empty());
- EXPECT_EQ(10, button.GetImageToPaint().width());
- EXPECT_EQ(20, button.GetImageToPaint().height());
+ EXPECT_FALSE(button.GetImageToPaint(kRequestedScale).empty());
+ EXPECT_EQ(10, button.GetImageToPaint(kRequestedScale).width());
+ EXPECT_EQ(20, button.GetImageToPaint(kRequestedScale).height());
// Preferred size is the normal button size.
EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
@@ -55,9 +57,9 @@ TEST_F(ImageButtonTest, Basics) {
EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
// We're still painting the normal image.
- EXPECT_FALSE(button.GetImageToPaint().empty());
- EXPECT_EQ(10, button.GetImageToPaint().width());
- EXPECT_EQ(20, button.GetImageToPaint().height());
+ EXPECT_FALSE(button.GetImageToPaint(kRequestedScale).empty());
+ EXPECT_EQ(10, button.GetImageToPaint(kRequestedScale).width());
+ EXPECT_EQ(20, button.GetImageToPaint(kRequestedScale).height());
// Set an overlay image.
gfx::ImageSkia overlay_image = CreateTestImage(12, 22);
@@ -70,9 +72,9 @@ TEST_F(ImageButtonTest, Basics) {
EXPECT_EQ("10x20", button.GetPreferredSize().ToString());
// We're still painting the normal image.
- EXPECT_FALSE(button.GetImageToPaint().empty());
- EXPECT_EQ(10, button.GetImageToPaint().width());
- EXPECT_EQ(20, button.GetImageToPaint().height());
+ EXPECT_FALSE(button.GetImageToPaint(kRequestedScale).empty());
+ EXPECT_EQ(10, button.GetImageToPaint(kRequestedScale).width());
+ EXPECT_EQ(20, button.GetImageToPaint(kRequestedScale).height());
// Reset the overlay image.
button.SetOverlayImage(NULL);