summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-27 17:58:41 +0000
committerpkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-27 17:58:41 +0000
commit3b2591a63e8033c17ba74e522e3def318d6e7377 (patch)
treed6127171e9bdd2ce17f050b980dc1a8ba194515e
parentda596cd33eb81af1a129d71c96384b9b353ae3ae (diff)
downloadchromium_src-3b2591a63e8033c17ba74e522e3def318d6e7377.zip
chromium_src-3b2591a63e8033c17ba74e522e3def318d6e7377.tar.gz
chromium_src-3b2591a63e8033c17ba74e522e3def318d6e7377.tar.bz2
Add ability to build a canvas with a target scale factor.
This allows ExtractBitmap() to return an ImageSkiaRep. This simplifies code around using intermediate bitmaps a lot. BUG=131475 TEST=Compiles R=oshima,sky TBR=sadrul Review URL: https://chromiumcodereview.appspot.com/10562027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144489 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/status/network_menu_icon.cc11
-rw-r--r--chrome/renderer/print_web_view_helper.cc8
-rw-r--r--skia/ext/canvas_paint_common.h8
-rw-r--r--skia/ext/canvas_paint_mac.h18
-rw-r--r--ui/base/native_theme/native_theme_android.cc21
-rw-r--r--ui/base/native_theme/native_theme_base.cc21
-rw-r--r--ui/compositor/layer.cc12
-rw-r--r--ui/gfx/canvas.cc88
-rw-r--r--ui/gfx/canvas.h54
-rw-r--r--ui/gfx/canvas_skia_paint.h9
-rw-r--r--ui/views/controls/button/image_button.cc8
-rw-r--r--ui/views/controls/button/image_button.h4
-rw-r--r--ui/views/drag_utils.cc15
13 files changed, 195 insertions, 82 deletions
diff --git a/chrome/browser/chromeos/status/network_menu_icon.cc b/chrome/browser/chromeos/status/network_menu_icon.cc
index afaca40..ca976c4 100644
--- a/chrome/browser/chromeos/status/network_menu_icon.cc
+++ b/chrome/browser/chromeos/status/network_menu_icon.cc
@@ -762,13 +762,7 @@ const gfx::ImageSkia NetworkMenuIcon::GenerateImageFromComponents(
std::vector<gfx::ImageSkiaRep> image_reps = icon.image_reps();
for (std::vector<gfx::ImageSkiaRep>::iterator it = image_reps.begin();
it != image_reps.end(); ++it) {
- float dip_scale = it->GetScale();
- gfx::Canvas canvas(it->sk_bitmap(), false);
- // TODO(kevers): This looks ugly, but gfx::Canvas::Scale is restricted to
- // integer scale factors. Consider adding a method to gfx::Canvas for
- // float scale factors.
- canvas.sk_canvas()->scale(SkFloatToScalar(dip_scale),
- SkFloatToScalar(dip_scale));
+ gfx::Canvas canvas(*it, false);
if (top_left_badge)
canvas.DrawImageInt(*top_left_badge, kBadgeLeftX, kBadgeTopY);
if (top_right_badge)
@@ -783,8 +777,7 @@ const gfx::ImageSkia NetworkMenuIcon::GenerateImageFromComponents(
canvas.DrawImageInt(*bottom_right_badge,
dip_width - bottom_right_badge->width(),
dip_height - bottom_right_badge->height());
- badged.AddRepresentation(gfx::ImageSkiaRep(canvas.ExtractBitmap(),
- it->scale_factor()));
+ badged.AddRepresentation(canvas.ExtractImageSkiaRep());
}
return badged;
}
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index bfcf5f9..4e10cf2 100644
--- a/chrome/renderer/print_web_view_helper.cc
+++ b/chrome/renderer/print_web_view_helper.cc
@@ -34,11 +34,12 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPrintScalingOption.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/layout.h"
#include "ui/gfx/rect.h"
#include "webkit/glue/webpreferences.h"
@@ -482,7 +483,10 @@ void PrintHeaderFooterByRenderText(
int save_count = canvas->save();
canvas->translate(-margin_left, -margin_top);
{
- gfx::Canvas gfx_canvas(canvas);
+ SkMatrix m = canvas->getTotalMatrix();
+ ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
+ SkScalarAbs(m.getScaleX()));
+ gfx::Canvas gfx_canvas(canvas, device_scale_factor, false);
render_text->Draw(&gfx_canvas);
}
canvas->restoreToCount(save_count);
diff --git a/skia/ext/canvas_paint_common.h b/skia/ext/canvas_paint_common.h
index 6eed3f4..cc762a2 100644
--- a/skia/ext/canvas_paint_common.h
+++ b/skia/ext/canvas_paint_common.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,6 +13,12 @@ template<class T> inline PlatformCanvas* GetPlatformCanvas(T* t) {
return t;
}
+// TODO(pkotwicz): Push scale into PlatformCanvas such that this function
+// is not needed.
+template<class T> inline void RecreateBackingCanvas(T* t,
+ int width, int height, float scale, bool opaque) {
+}
+
} // namespace skia
#endif // SKIA_EXT_CANVAS_PAINT_COMMON_H_
diff --git a/skia/ext/canvas_paint_mac.h b/skia/ext/canvas_paint_mac.h
index 56dc2e9..8e6a350 100644
--- a/skia/ext/canvas_paint_mac.h
+++ b/skia/ext/canvas_paint_mac.h
@@ -87,24 +87,18 @@ class CanvasPaintT : public T {
(CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGRect scaled_unit_rect = CGContextConvertRectToDeviceSpace(
destination_context, CGRectMake(0, 0, 1, 1));
- CGFloat x_scale = scaled_unit_rect.size.width;
- CGFloat y_scale = scaled_unit_rect.size.height;
+ // Assume that the x scale and the y scale are the same.
+ CGFloat scale = scaled_unit_rect.size.width;
+ RecreateBackingCanvas(this,
+ NSWidth(rectangle_), NSHeight(rectangle_), scale, opaque);
PlatformCanvas* canvas = GetPlatformCanvas(this);
- if (!canvas->initialize(NSWidth(rectangle_) * x_scale,
- NSHeight(rectangle_) * y_scale,
- opaque, NULL)) {
- // Cause a deliberate crash.
- *(volatile char*) 0 = 0;
- }
canvas->clear(SkColorSetARGB(0, 0, 0, 0));
// Need to translate so that the dirty region appears at the origin of the
// surface.
- canvas->translate(-SkDoubleToScalar(NSMinX(rectangle_) * x_scale),
- -SkDoubleToScalar(NSMinY(rectangle_) * y_scale));
- // Scale appropriately.
- canvas->scale(SkFloatToScalar(x_scale), SkFloatToScalar(y_scale));
+ canvas->translate(-SkDoubleToScalar(NSMinX(rectangle_)),
+ -SkDoubleToScalar(NSMinY(rectangle_)));
context_ = GetBitmapContext(GetTopDevice(*canvas));
}
diff --git a/ui/base/native_theme/native_theme_android.cc b/ui/base/native_theme/native_theme_android.cc
index 354bd0f..a9165e8 100644
--- a/ui/base/native_theme/native_theme_android.cc
+++ b/ui/base/native_theme/native_theme_android.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "grit/ui_resources_standard.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_utils.h"
@@ -654,7 +655,7 @@ bool NativeThemeAndroid::IntersectsClipRectInt(SkCanvas* canvas,
SkIntToScalar(y + h));
}
-void NativeThemeAndroid::DrawImageInt(SkCanvas* canvas,
+void NativeThemeAndroid::DrawImageInt(SkCanvas* sk_canvas,
const gfx::ImageSkia& image,
int src_x,
int src_y,
@@ -664,11 +665,17 @@ void NativeThemeAndroid::DrawImageInt(SkCanvas* canvas,
int dest_y,
int dest_w,
int dest_h) const {
- gfx::Canvas(canvas).DrawImageInt(image, src_x, src_y, src_w, src_h,
+ // TODO(pkotwicz): Do something better and don't infer device
+ // scale factor from canvas scale.
+ SkMatrix m = sk_canvas->getTotalMatrix();
+ ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
+ SkScalarAbs(m.getScaleX()));
+ gfx::Canvas canvas(sk_canvas, device_scale_factor, false);
+ canvas.DrawImageInt(image, src_x, src_y, src_w, src_h,
dest_x, dest_y, dest_w, dest_h, true);
}
-void NativeThemeAndroid::DrawTiledImage(SkCanvas* canvas,
+void NativeThemeAndroid::DrawTiledImage(SkCanvas* sk_canvas,
const gfx::ImageSkia& image,
int src_x,
int src_y,
@@ -678,7 +685,13 @@ void NativeThemeAndroid::DrawTiledImage(SkCanvas* canvas,
int dest_y,
int w,
int h) const {
- gfx::Canvas(canvas).TileImageInt(image, src_x, src_y, tile_scale_x,
+ // TODO(pkotwicz): Do something better and don't infer device
+ // scale factor from canvas scale.
+ SkMatrix m = sk_canvas->getTotalMatrix();
+ ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
+ SkScalarAbs(m.getScaleX()));
+ gfx::Canvas canvas(sk_canvas, device_scale_factor, false);
+ canvas.TileImageInt(image, src_x, src_y, tile_scale_x,
tile_scale_y, dest_x, dest_y, w, h);
}
diff --git a/ui/base/native_theme/native_theme_base.cc b/ui/base/native_theme/native_theme_base.cc
index 54744cf..b734b17 100644
--- a/ui/base/native_theme/native_theme_base.cc
+++ b/ui/base/native_theme/native_theme_base.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "grit/ui_resources_standard.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/canvas.h"
@@ -1011,18 +1012,30 @@ bool NativeThemeBase::IntersectsClipRectInt(SkCanvas* canvas,
}
void NativeThemeBase::DrawImageInt(
- SkCanvas* canvas, const gfx::ImageSkia& image,
+ SkCanvas* sk_canvas, const gfx::ImageSkia& image,
int src_x, int src_y, int src_w, int src_h,
int dest_x, int dest_y, int dest_w, int dest_h) const {
- gfx::Canvas(canvas).DrawImageInt(image, src_x, src_y, src_w, src_h,
+ // TODO(pkotwicz): Do something better and don't infer device
+ // scale factor from canvas scale.
+ SkMatrix m = sk_canvas->getTotalMatrix();
+ ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
+ SkScalarAbs(m.getScaleX()));
+ gfx::Canvas canvas(sk_canvas, device_scale_factor, false);
+ canvas.DrawImageInt(image, src_x, src_y, src_w, src_h,
dest_x, dest_y, dest_w, dest_h, true);
}
-void NativeThemeBase::DrawTiledImage(SkCanvas* canvas,
+void NativeThemeBase::DrawTiledImage(SkCanvas* sk_canvas,
const gfx::ImageSkia& image,
int src_x, int src_y, float tile_scale_x, float tile_scale_y,
int dest_x, int dest_y, int w, int h) const {
- gfx::Canvas(canvas).TileImageInt(image, src_x, src_y, tile_scale_x,
+ // TODO(pkotwicz): Do something better and don't infer device
+ // scale factor from canvas scale.
+ SkMatrix m = sk_canvas->getTotalMatrix();
+ ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
+ SkScalarAbs(m.getScaleX()));
+ gfx::Canvas canvas(sk_canvas, device_scale_factor, false);
+ canvas.TileImageInt(image, src_x, src_y, tile_scale_x,
tile_scale_y, dest_x, dest_y, w, h);
}
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index 47098e7..5726770 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -424,17 +424,11 @@ void Layer::paintContents(WebKit::WebCanvas* web_canvas,
const WebKit::WebRect& clip,
WebKit::WebRect& opaque) {
TRACE_EVENT0("ui", "Layer::paintContents");
- gfx::Canvas canvas(web_canvas);
- bool scale_content = scale_content_;
- if (scale_content) {
- canvas.Save();
- canvas.sk_canvas()->scale(SkFloatToScalar(device_scale_factor_),
- SkFloatToScalar(device_scale_factor_));
- }
+ gfx::Canvas canvas(web_canvas,
+ ui::GetScaleFactorFromScale(device_scale_factor_), scale_content_);
+
if (delegate_)
delegate_->OnPaintLayer(&canvas);
- if (scale_content)
- canvas.Restore();
}
void Layer::SetForceRenderSurface(bool force) {
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
index a7bc247..f0208a3 100644
--- a/ui/gfx/canvas.cc
+++ b/ui/gfx/canvas.cc
@@ -32,27 +32,69 @@ Canvas::Canvas(const gfx::Size& size, bool is_opaque)
if (!is_opaque)
owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0));
#endif
+
+ ApplyScaleFactor(ui::SCALE_FACTOR_100P, false);
}
-Canvas::Canvas(const SkBitmap& bitmap, bool is_opaque)
- : owned_canvas_(new skia::PlatformCanvas(bitmap.width(), bitmap.height(),
+Canvas::Canvas(const gfx::Size& size,
+ ui::ScaleFactor scale_factor,
+ bool is_opaque) {
+ gfx::Size pixel_size = size.Scale(ui::GetScaleFactorScale(scale_factor));
+ owned_canvas_.reset(new skia::PlatformCanvas(pixel_size.width(),
+ pixel_size.height(),
+ is_opaque));
+ canvas_ = owned_canvas_.get();
+#if defined(OS_WIN) || defined(OS_MACOSX)
+ // skia::PlatformCanvas instances are initialized to 0 by Cairo on Linux, but
+ // uninitialized on Win and Mac.
+ if (!is_opaque)
+ owned_canvas_->clear(SkColorSetARGB(0, 0, 0, 0));
+#endif
+
+ ApplyScaleFactor(scale_factor, true);
+}
+
+Canvas::Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque)
+ : owned_canvas_(new skia::PlatformCanvas(image_rep.pixel_width(),
+ image_rep.pixel_height(),
is_opaque)),
canvas_(owned_canvas_.get()) {
- DrawImageInt(bitmap, 0, 0);
+ ApplyScaleFactor(image_rep.scale_factor(), true);
+ DrawImageInt(gfx::ImageSkia(image_rep), 0, 0);
}
Canvas::Canvas()
: owned_canvas_(new skia::PlatformCanvas()),
canvas_(owned_canvas_.get()) {
+ ApplyScaleFactor(ui::SCALE_FACTOR_100P, false);
}
-Canvas::Canvas(SkCanvas* canvas)
+Canvas::Canvas(SkCanvas* canvas,
+ ui::ScaleFactor scale_factor,
+ bool scale_canvas)
: owned_canvas_(),
canvas_(canvas) {
DCHECK(canvas);
+ ApplyScaleFactor(scale_factor, scale_canvas);
}
Canvas::~Canvas() {
+ if (scale_factor_scales_canvas_) {
+ SkScalar scale = 1.0f / ui::GetScaleFactorScale(scale_factor_);
+ canvas_->scale(scale, scale);
+ }
+}
+
+void Canvas::RecreateBackingCanvas(const gfx::Size& size,
+ ui::ScaleFactor scale_factor,
+ bool is_opaque) {
+ gfx::Size pixel_size = size.Scale(ui::GetScaleFactorScale(scale_factor));
+ owned_canvas_.reset(new skia::PlatformCanvas(pixel_size.width(),
+ pixel_size.height(),
+ is_opaque));
+ canvas_ = owned_canvas_.get();
+
+ ApplyScaleFactor(scale_factor, true);
}
// static
@@ -78,6 +120,10 @@ SkBitmap Canvas::ExtractBitmap() const {
return result;
}
+gfx::ImageSkiaRep Canvas::ExtractImageSkiaRep() const {
+ return gfx::ImageSkiaRep(ExtractBitmap(), scale_factor_);
+}
+
void Canvas::DrawDashedRect(const gfx::Rect& rect, SkColor color) {
// Create a 2D bitmap containing alternating on/off pixels - we do this
// so that you never get two pixels of the same color around the edges
@@ -458,6 +504,15 @@ bool Canvas::IntersectsClipRect(const gfx::Rect& rect) {
rect.width(), rect.height());
}
+void Canvas::ApplyScaleFactor(ui::ScaleFactor scale_factor,
+ bool scale_canvas) {
+ scale_factor_scales_canvas_ = scale_canvas;
+ scale_factor_ = scale_factor;
+ if (scale_canvas) {
+ SkScalar scale = SkFloatToScalar(ui::GetScaleFactorScale(scale_factor));
+ canvas_->scale(scale, scale);
+ }
+}
const SkBitmap& Canvas::GetBitmapToPaint(const gfx::ImageSkia& image,
float* bitmap_scale_factor) const {
@@ -468,21 +523,20 @@ const SkBitmap& Canvas::GetBitmapToPaint(const gfx::ImageSkia& image,
float user_additional_scale_x,
float user_additional_scale_y,
float* bitmap_scale_factor) const {
- SkMatrix m = canvas_->getTotalMatrix();
- float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) *
- user_additional_scale_x;
- float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) *
- user_additional_scale_y;
-
- ui::ScaleFactor request_scale_factor =
- ui::GetScaleFactorFromScale((scale_x + scale_y) / 2);
- const gfx::ImageSkiaRep& image_rep =
- image.GetRepresentation(request_scale_factor);
+ const gfx::ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor_);
const SkBitmap& bitmap = image_rep.sk_bitmap();
*bitmap_scale_factor = image_rep.GetScale();
- if (!bitmap.isNull() &&
- (scale_x < *bitmap_scale_factor || scale_y < *bitmap_scale_factor))
- const_cast<SkBitmap&>(bitmap).buildMipMap();
+
+ if (!bitmap.isNull()) {
+ SkMatrix m = canvas_->getTotalMatrix();
+ float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) *
+ user_additional_scale_x;
+ float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) *
+ user_additional_scale_y;
+
+ if (scale_x < *bitmap_scale_factor || scale_y < *bitmap_scale_factor)
+ const_cast<SkBitmap&>(bitmap).buildMipMap();
+ }
return bitmap;
}
diff --git a/ui/gfx/canvas.h b/ui/gfx/canvas.h
index 6780774..e7af178 100644
--- a/ui/gfx/canvas.h
+++ b/ui/gfx/canvas.h
@@ -98,21 +98,44 @@ class UI_EXPORT Canvas {
NO_SUBPIXEL_RENDERING = 1 << 13,
};
- // Creates an empty canvas.
+ // Creates an empty canvas with scale factor of 1x.
Canvas();
+ // Creates canvas with provided DIP |size| and a scale factor of 1x.
// If this canvas is not opaque, it's explicitly cleared to transparent before
// being returned.
+ // TODO(pkotwicz): Remove this constructor.
Canvas(const gfx::Size& size, bool is_opaque);
- // Constructs a canvas the size of the provided |bitmap|, and draws the
- // bitmap into it.
- Canvas(const SkBitmap& bitmap, bool is_opaque);
+ // Creates canvas with provided DIP |size| and |scale_factor|.
+ // If this canvas is not opaque, it's explicitly cleared to transparent before
+ // being returned.
+ Canvas(const gfx::Size& size,
+ ui::ScaleFactor scale_factor,
+ bool is_opaque);
- explicit Canvas(SkCanvas* canvas);
+ // Constructs a canvas with the size and the scale factor of the
+ // provided |image_rep|, and draws the |image_rep| into it.
+ Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque);
+
+ // Sets scale factor to |scale_factor|.
+ // Only scales canvas if |scale_canvas| is true.
+ Canvas(SkCanvas* canvas,
+ ui::ScaleFactor scale_factor,
+ bool scale_canvas);
virtual ~Canvas();
+ // Recreates the backing platform canvas with DIP |size| and |scale_factor|.
+ // If the canvas is not opaque, it is explicitly cleared.
+ // This method is public so that canvas_skia_paint can recreate the platform
+ // canvas after having initialized the canvas.
+ // TODO(pkotwicz): Push the scale factor into skia::PlatformCanvas such that
+ // this method can be private.
+ void RecreateBackingCanvas(const gfx::Size& size,
+ ui::ScaleFactor scale_factor,
+ bool is_opaque);
+
// Compute the size required to draw some text with the provided font.
// Attempts to fit the text with the provided width and height. Increases
// height and then width as needed to make the text fit. This method
@@ -152,8 +175,13 @@ class UI_EXPORT Canvas {
int flags);
// Extracts a bitmap from the contents of this canvas.
+ // TODO(pkotwicz): Remove ExtractBitmap once all callers use
+ // ExtractImageSkiaRep instead.
SkBitmap ExtractBitmap() const;
+ // Extracts an ImageSkiaRep from the contents of this canvas.
+ gfx::ImageSkiaRep ExtractImageSkiaRep() const;
+
// Draws a dashed rectangle of the specified color.
void DrawDashedRect(const gfx::Rect& rect, SkColor color);
@@ -351,12 +379,19 @@ class UI_EXPORT Canvas {
skia::PlatformCanvas* platform_canvas() const { return owned_canvas_.get(); }
SkCanvas* sk_canvas() const { return canvas_; }
+ ui::ScaleFactor scale_factor() const { return scale_factor_; }
private:
// Test whether the provided rectangle intersects the current clip rect.
bool IntersectsClipRectInt(int x, int y, int w, int h);
bool IntersectsClipRect(const gfx::Rect& rect);
+ // Sets the canvas' scale factor to |scale_factor|. This affects
+ // the scale factor at which drawing bitmaps occurs and the scale factor of
+ // the image rep returned by Canvas::ExtractImageSkiaRep().
+ // If |scale_canvas| is true, scales the canvas by |scale_factor|.
+ void ApplyScaleFactor(ui::ScaleFactor scale_factor, bool scale_canvas);
+
// Returns the bitmap whose density best matches the current canvas scale.
// Returns a null bitmap if |image| contains no bitmaps.
// |bitmap_scale_factor| is set to the scale factor of the returned bitmap.
@@ -384,6 +419,15 @@ class UI_EXPORT Canvas {
scoped_ptr<skia::PlatformCanvas> owned_canvas_;
SkCanvas* canvas_;
+ // True if the scale factor scales the canvas and the inverse
+ // canvas scale should be applied when the destructor is called.
+ bool scale_factor_scales_canvas_;
+
+ // The device scale factor at which drawing on this canvas occurs.
+ // An additional scale can be applied via Canvas::Scale(). However,
+ // Canvas::Scale() does not affect |scale_factor_|.
+ ui::ScaleFactor scale_factor_;
+
DISALLOW_COPY_AND_ASSIGN(Canvas);
};
diff --git a/ui/gfx/canvas_skia_paint.h b/ui/gfx/canvas_skia_paint.h
index 885bf32..3ee6fca 100644
--- a/ui/gfx/canvas_skia_paint.h
+++ b/ui/gfx/canvas_skia_paint.h
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "skia/ext/canvas_paint.h"
#include "ui/gfx/canvas.h"
+#include "ui/gfx/size.h"
// Define a gfx::CanvasSkiaPaint type that wraps our gfx::Canvas like the
// skia::PlatformCanvasPaint wraps PlatformCanvas.
@@ -22,6 +23,14 @@ PlatformCanvas* GetPlatformCanvas(skia::CanvasPaintT<gfx::Canvas>* canvas) {
return platform_canvas;
}
+template<> inline
+void RecreateBackingCanvas(skia::CanvasPaintT<gfx::Canvas>* canvas,
+ int width, int height, float scale, bool opaque) {
+ ui::ScaleFactor scale_factor = ui::GetScaleFactorFromScale(scale);
+ canvas->RecreateBackingCanvas(gfx::Size(width, height), scale_factor,
+ opaque);
+}
+
} // namespace skia
namespace gfx {
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc
index 1af311b..a1b05c8 100644
--- a/ui/views/controls/button/image_button.cc
+++ b/ui/views/controls/button/image_button.cc
@@ -75,7 +75,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 = GetCurrentDeviceScaleFactor();
+ ui::ScaleFactor current_device_scale_factor = canvas->scale_factor();
gfx::ImageSkia img = GetImageToPaint(current_device_scale_factor);
if (!img.isNull()) {
@@ -109,12 +109,6 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) {
////////////////////////////////////////////////////////////////////////////////
// ImageButton, protected:
-ui::ScaleFactor ImageButton::GetCurrentDeviceScaleFactor() {
- gfx::Display display = gfx::Screen::GetDisplayNearestWindow(
- GetWidget() ? GetWidget()->GetNativeView() : NULL);
- return ui::GetScaleFactorFromScale(display.device_scale_factor());
-}
-
gfx::ImageSkia ImageButton::GetImageToPaint(ui::ScaleFactor scale_factor) {
gfx::ImageSkia img;
diff --git a/ui/views/controls/button/image_button.h b/ui/views/controls/button/image_button.h
index 413a4bc..5d1ae01 100644
--- a/ui/views/controls/button/image_button.h
+++ b/ui/views/controls/button/image_button.h
@@ -63,10 +63,6 @@ class VIEWS_EXPORT ImageButton : public CustomButton {
}
protected:
- // Returns the current device scale factor of the view.
- // TODO(pkotwicz): Remove this once scale factor can be queried from canvas.
- ui::ScaleFactor GetCurrentDeviceScaleFactor();
-
// 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
diff --git a/ui/views/drag_utils.cc b/ui/views/drag_utils.cc
index a0bc0f2..09812d9 100644
--- a/ui/views/drag_utils.cc
+++ b/ui/views/drag_utils.cc
@@ -22,8 +22,8 @@
#error
#endif
-float GetDeviceScaleFactorForNativeView(views::Widget* widget) {
- float device_scale_factor = 1;
+ui::ScaleFactor GetDeviceScaleFactorForNativeView(views::Widget* widget) {
+ ui::ScaleFactor device_scale_factor = ui::SCALE_FACTOR_100P;
#if defined(USE_AURA)
// The following code should work on other platforms as well. But we do not
// yet care about device scale factor on other platforms. So to keep drag and
@@ -31,7 +31,8 @@ float GetDeviceScaleFactorForNativeView(views::Widget* widget) {
if (widget && widget->GetNativeView()) {
gfx::Display display = gfx::Screen::GetDisplayNearestWindow(
widget->GetNativeView());
- device_scale_factor = display.device_scale_factor();
+ device_scale_factor = ui::GetScaleFactorFromScale(
+ display.device_scale_factor());
}
#endif
return device_scale_factor;
@@ -63,11 +64,9 @@ void RunShellDrag(gfx::NativeView view,
gfx::Canvas* GetCanvasForDragImage(views::Widget* widget,
const gfx::Size& canvas_size) {
- float device_scale_factor = GetDeviceScaleFactorForNativeView(widget);
- gfx::Size scaled_canvas_size = canvas_size.Scale(device_scale_factor);
- gfx::Canvas* canvas = new gfx::Canvas(scaled_canvas_size, false);
- canvas->Scale(device_scale_factor, device_scale_factor);
- return canvas;
+ ui::ScaleFactor device_scale_factor =
+ GetDeviceScaleFactorForNativeView(widget);
+ return new gfx::Canvas(canvas_size, device_scale_factor, false);
}
} // namespace views