diff options
author | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-27 17:58:41 +0000 |
---|---|---|
committer | pkotwicz@chromium.org <pkotwicz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-27 17:58:41 +0000 |
commit | 3b2591a63e8033c17ba74e522e3def318d6e7377 (patch) | |
tree | d6127171e9bdd2ce17f050b980dc1a8ba194515e /ui/gfx | |
parent | da596cd33eb81af1a129d71c96384b9b353ae3ae (diff) | |
download | chromium_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
Diffstat (limited to 'ui/gfx')
-rw-r--r-- | ui/gfx/canvas.cc | 88 | ||||
-rw-r--r-- | ui/gfx/canvas.h | 54 | ||||
-rw-r--r-- | ui/gfx/canvas_skia_paint.h | 9 |
3 files changed, 129 insertions, 22 deletions
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 { |