summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/base/resource/resource_bundle.cc22
-rw-r--r--ui/gfx/canvas.cc107
-rw-r--r--ui/gfx/canvas.h56
-rw-r--r--ui/gfx/image/image.cc35
-rw-r--r--ui/gfx/image/image.h8
-rw-r--r--ui/gfx/image/image_mac.mm37
-rw-r--r--ui/gfx/image/image_mac_unittest.mm96
-rw-r--r--ui/gfx/image/image_skia.cc255
-rw-r--r--ui/gfx/image/image_skia.h155
-rw-r--r--ui/gfx/image/image_unittest.cc66
10 files changed, 322 insertions, 515 deletions
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc
index f84e8db..bb011ab 100644
--- a/ui/base/resource/resource_bundle.cc
+++ b/ui/base/resource/resource_bundle.cc
@@ -24,7 +24,6 @@
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/image/image_skia.h"
namespace ui {
@@ -232,26 +231,25 @@ gfx::Image& ResourceBundle::GetImageNamed(int resource_id) {
if (image.IsEmpty()) {
DCHECK(!delegate_ && !data_packs_.empty()) <<
"Missing call to SetResourcesDataDLL?";
- gfx::ImageSkia image_skia;
+ ScopedVector<const SkBitmap> bitmaps;
for (size_t i = 0; i < data_packs_.size(); ++i) {
- scoped_ptr<SkBitmap> bitmap(LoadBitmap(*data_packs_[i], resource_id));
- if (bitmap.get()) {
-#if defined(ENABLE_DIP)
- image_skia.AddBitmapForScale(*bitmap, data_packs_[i]->GetScaleFactor());
-#else
- image_skia.AddBitmapForScale(*bitmap, 1.0f);
-#endif
- }
+ SkBitmap* bitmap = LoadBitmap(*data_packs_[i], resource_id);
+ if (bitmap)
+ bitmaps.push_back(bitmap);
}
- if (image_skia.empty()) {
+ if (bitmaps.empty()) {
LOG(WARNING) << "Unable to load image with id " << resource_id;
NOTREACHED(); // Want to assert in debug mode.
// The load failed to retrieve the image; show a debugging red square.
return GetEmptyImage();
}
- image = gfx::Image(image_skia);
+ std::vector<const SkBitmap*> tmp_bitmaps;
+ bitmaps.release(&tmp_bitmaps);
+
+ // Takes ownership of bitmaps.
+ image = gfx::Image(tmp_bitmaps);
}
// The load was successful, so cache the image.
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
index aeabc12..288d192 100644
--- a/ui/gfx/canvas.cc
+++ b/ui/gfx/canvas.cc
@@ -254,42 +254,42 @@ void Canvas::DrawFocusRect(const gfx::Rect& rect) {
DrawDashedRect(rect, SK_ColorGRAY);
}
-void Canvas::DrawBitmapInt(const gfx::ImageSkia& image, int x, int y) {
- SkPaint paint;
- DrawBitmapInt(image, x, y, paint);
+void Canvas::DrawBitmapInt(const SkBitmap& bitmap, int x, int y) {
+ canvas_->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y));
}
-void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
+void Canvas::DrawBitmapInt(const SkBitmap& bitmap,
int x, int y,
const SkPaint& paint) {
- float bitmap_scale;
- const SkBitmap& bitmap = GetBitmapToPaint(image, &bitmap_scale);
- if (bitmap.isNull())
- return;
-
- canvas_->save();
- canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale),
- SkFloatToScalar(1.0f / bitmap_scale));
- canvas_->drawBitmap(bitmap,
- SkFloatToScalar(x * bitmap_scale),
- SkFloatToScalar(y * bitmap_scale));
- canvas_->restore();
+ canvas_->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), &paint);
}
-void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
+void Canvas::DrawBitmapInt(const SkBitmap& bitmap,
int src_x, int src_y, int src_w, int src_h,
int dest_x, int dest_y, int dest_w, int dest_h,
bool filter) {
SkPaint p;
- DrawBitmapInt(image, src_x, src_y, src_w, src_h, dest_x, dest_y,
+ DrawBitmapInt(bitmap, src_x, src_y, src_w, src_h, dest_x, dest_y,
dest_w, dest_h, filter, p);
}
-void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
+void Canvas::DrawBitmapInt(const SkBitmap& bitmap,
int src_x, int src_y, int src_w, int src_h,
int dest_x, int dest_y, int dest_w, int dest_h,
bool filter,
const SkPaint& paint) {
+ DrawBitmapFloat(bitmap, static_cast<float>(src_x), static_cast<float>(src_y),
+ static_cast<float>(src_w), static_cast<float>(src_h),
+ static_cast<float>(dest_x), static_cast<float>(dest_y),
+ static_cast<float>(dest_w), static_cast<float>(dest_h),
+ filter, paint);
+}
+
+void Canvas::DrawBitmapFloat(const SkBitmap& bitmap,
+ float src_x, float src_y, float src_w, float src_h,
+ float dest_x, float dest_y, float dest_w, float dest_h,
+ bool filter,
+ const SkPaint& paint) {
DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() &&
src_y + src_h < std::numeric_limits<int16_t>::max());
if (src_w <= 0 || src_h <= 0) {
@@ -300,22 +300,12 @@ void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h))
return;
- float user_scale_x = static_cast<float>(dest_w) / src_w;
- float user_scale_y = static_cast<float>(dest_h) / src_h;
+ SkRect dest_rect = { SkFloatToScalar(dest_x),
+ SkFloatToScalar(dest_y),
+ SkFloatToScalar(dest_x + dest_w),
+ SkFloatToScalar(dest_y + dest_h) };
- float bitmap_scale;
- const SkBitmap& bitmap = GetBitmapToPaint(image, user_scale_x, user_scale_y,
- &bitmap_scale);
- if (bitmap.isNull())
- return;
-
- SkRect dest_rect = { SkIntToScalar(dest_x),
- SkIntToScalar(dest_y),
- SkIntToScalar(dest_x + dest_w),
- SkIntToScalar(dest_y + dest_h) };
-
- if (src_w == dest_w && src_h == dest_h &&
- bitmap_scale == 1.0f && bitmap_scale == 1.0f) {
+ if (src_w == dest_w && src_h == dest_h) {
// Workaround for apparent bug in Skia that causes image to occasionally
// shift.
SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h };
@@ -331,13 +321,10 @@ void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
SkShader::kRepeat_TileMode,
SkShader::kRepeat_TileMode);
SkMatrix shader_scale;
- shader_scale.setScale(SkFloatToScalar(user_scale_x),
- SkFloatToScalar(user_scale_y));
- shader_scale.preTranslate(SkFloatToScalar(-src_x * bitmap_scale),
- SkFloatToScalar(-src_y * bitmap_scale));
- shader_scale.postTranslate(SkFloatToScalar(dest_x * bitmap_scale),
- SkFloatToScalar(dest_y * bitmap_scale));
- shader_scale.postScale(1.0f / bitmap_scale, 1.0f / bitmap_scale);
+ shader_scale.setScale(SkFloatToScalar(dest_w / src_w),
+ SkFloatToScalar(dest_h / src_h));
+ shader_scale.preTranslate(SkFloatToScalar(-src_x), SkFloatToScalar(-src_y));
+ shader_scale.postTranslate(SkFloatToScalar(dest_x), SkFloatToScalar(dest_y));
shader->setLocalMatrix(shader_scale);
// Set up our paint to use the shader & release our reference (now just owned
@@ -379,22 +366,17 @@ void Canvas::DrawStringInt(const string16& text,
std::vector<ShadowValue>());
}
-void Canvas::TileImageInt(const gfx::ImageSkia& image,
+void Canvas::TileImageInt(const SkBitmap& bitmap,
int x, int y, int w, int h) {
- TileImageInt(image, 0, 0, x, y, w, h);
+ TileImageInt(bitmap, 0, 0, x, y, w, h);
}
-void Canvas::TileImageInt(const gfx::ImageSkia& image,
+void Canvas::TileImageInt(const SkBitmap& bitmap,
int src_x, int src_y,
int dest_x, int dest_y, int w, int h) {
if (!IntersectsClipRectInt(dest_x, dest_y, w, h))
return;
- float bitmap_scale;
- const SkBitmap& bitmap = GetBitmapToPaint(image, &bitmap_scale);
- if (bitmap.isNull())
- return;
-
SkPaint paint;
SkShader* shader = SkShader::CreateBitmapShader(bitmap,
@@ -410,8 +392,6 @@ void Canvas::TileImageInt(const gfx::ImageSkia& image,
canvas_->translate(SkIntToScalar(dest_x - src_x),
SkIntToScalar(dest_y - src_y));
ClipRect(gfx::Rect(src_x, src_y, w, h));
- canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale),
- SkFloatToScalar(1.0f / bitmap_scale));
canvas_->drawPaint(paint);
canvas_->restore();
}
@@ -440,29 +420,4 @@ bool Canvas::IntersectsClipRect(const gfx::Rect& rect) {
rect.width(), rect.height());
}
-
-const SkBitmap& Canvas::GetBitmapToPaint(const gfx::ImageSkia& image,
- float* bitmap_scale_factor) const {
- return GetBitmapToPaint(image, 1.0f, 1.0f, bitmap_scale_factor);
-}
-
-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;
-
- const SkBitmap& bitmap = image.GetBitmapForScale(scale_x, scale_y,
- bitmap_scale_factor);
- if (!bitmap.isNull() &&
- (scale_x < *bitmap_scale_factor || scale_y < *bitmap_scale_factor))
- const_cast<SkBitmap&>(bitmap).buildMipMap();
-
- return bitmap;
-}
-
} // namespace gfx
diff --git a/ui/gfx/canvas.h b/ui/gfx/canvas.h
index 69f402b..7653f39 100644
--- a/ui/gfx/canvas.h
+++ b/ui/gfx/canvas.h
@@ -12,7 +12,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "skia/ext/platform_canvas.h"
-#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/native_widget_types.h"
class SkBitmap;
@@ -241,43 +240,47 @@ class UI_EXPORT Canvas {
// Draws the given path using the given |paint| parameters.
void DrawPath(const SkPath& path, const SkPaint& paint);
- // Draws an image with the origin at the specified location. The upper left
+ // Draws a bitmap with the origin at the specified location. The upper left
// corner of the bitmap is rendered at the specified location.
- // Parameters are specified relative to current canvas scale not in pixels.
- // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
- void DrawBitmapInt(const gfx::ImageSkia&, int x, int y);
+ void DrawBitmapInt(const SkBitmap& bitmap, int x, int y);
- // Draws an image with the origin at the specified location, using the
+ // Draws a bitmap with the origin at the specified location, using the
// specified paint. The upper left corner of the bitmap is rendered at the
// specified location.
- // Parameters are specified relative to current canvas scale not in pixels.
- // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
- void DrawBitmapInt(const gfx::ImageSkia& image,
+ void DrawBitmapInt(const SkBitmap& bitmap,
int x, int y,
const SkPaint& paint);
- // Draws a portion of an image in the specified location. The src parameters
+ // Draws a portion of a bitmap in the specified location. The src parameters
// correspond to the region of the bitmap to draw in the region defined
// by the dest coordinates.
//
// If the width or height of the source differs from that of the destination,
- // the image will be scaled. When scaling down, a mipmap will be generated.
- // Set |filter| to use filtering for images, otherwise the nearest-neighbor
- // algorithm is used for resampling.
+ // the bitmap will be scaled. When scaling down, it is highly recommended
+ // that you call buildMipMap(false) on your bitmap to ensure that it has
+ // a mipmap, which will result in much higher-quality output. Set |filter|
+ // to use filtering for bitmaps, otherwise the nearest-neighbor algorithm
+ // is used for resampling.
//
// An optional custom SkPaint can be provided.
- // Parameters are specified relative to current canvas scale not in pixels.
- // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
- void DrawBitmapInt(const gfx::ImageSkia& image,
+ void DrawBitmapInt(const SkBitmap& bitmap,
int src_x, int src_y, int src_w, int src_h,
int dest_x, int dest_y, int dest_w, int dest_h,
bool filter);
- void DrawBitmapInt(const gfx::ImageSkia& image,
+ void DrawBitmapInt(const SkBitmap& bitmap,
int src_x, int src_y, int src_w, int src_h,
int dest_x, int dest_y, int dest_w, int dest_h,
bool filter,
const SkPaint& paint);
+ // TODO(pkotwicz): make this function private once gfx::ImageSkia stops
+ // calling this method.
+ void DrawBitmapFloat(const SkBitmap& bitmap,
+ float src_x, float src_y, float src_w, float src_h,
+ float dest_x, float dest_y, float dest_w, float dest_h,
+ bool filter,
+ const SkPaint& paint);
+
// Draws text with the specified color, font and location. The text is
// aligned to the left, vertically centered, clipped to the region. If the
// text is too big, it is truncated and '...' is added to the end.
@@ -312,11 +315,9 @@ class UI_EXPORT Canvas {
void DrawFocusRect(const gfx::Rect& rect);
// Tiles the image in the specified region.
- // Parameters are specified relative to current canvas scale not in pixels.
- // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
- void TileImageInt(const gfx::ImageSkia& image,
+ void TileImageInt(const SkBitmap& bitmap,
int x, int y, int w, int h);
- void TileImageInt(const gfx::ImageSkia& image,
+ void TileImageInt(const SkBitmap& bitmap,
int src_x, int src_y,
int dest_x, int dest_y, int w, int h);
@@ -353,19 +354,6 @@ class UI_EXPORT Canvas {
bool IntersectsClipRectInt(int x, int y, int w, int h);
bool IntersectsClipRect(const gfx::Rect& rect);
- // 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.
- // Builds mip map for returned bitmap if necessary.
- //
- // An optional additional user defined scale can be provided.
- const SkBitmap& GetBitmapToPaint(const gfx::ImageSkia& image,
- float* bitmap_scale_factor) const;
- const SkBitmap& GetBitmapToPaint(const gfx::ImageSkia& image,
- float user_defined_scale_factor_x,
- float user_defined_scale_factor_y,
- float* bitmap_scale_factor) const;
-
#if defined(OS_WIN)
// Draws text with the specified color, font and location. The text is
// aligned to the left, vertically centered, clipped to the region. If the
diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc
index dac2ccc..e748dd9 100644
--- a/ui/gfx/image/image.cc
+++ b/ui/gfx/image/image.cc
@@ -31,8 +31,7 @@ namespace internal {
#if defined(OS_MACOSX)
// This is a wrapper around gfx::NSImageToSkBitmap() because this cross-platform
// file cannot include the [square brackets] of ObjC.
-ImageSkia NSImageToImageSkia(NSImage* image);
-NSImage* ImageSkiaToNSImage(const ImageSkia* image);
+bool NSImageToSkBitmaps(NSImage* image, std::vector<const SkBitmap*>* bitmaps);
#endif
#if defined(TOOLKIT_GTK)
@@ -98,7 +97,6 @@ class ImageRep {
class ImageRepSkia : public ImageRep {
public:
- // Takes ownership of |image|.
explicit ImageRepSkia(ImageSkia* image)
: ImageRep(Image::kImageRepSkia),
image_(image) {
@@ -226,13 +224,6 @@ Image::Image() {
// |storage_| is NULL for empty Images.
}
-Image::Image(const ImageSkia& image)
- : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
- internal::ImageRepSkia* rep = new internal::ImageRepSkia(
- new ImageSkia(image));
- AddRepresentation(rep);
-}
-
Image::Image(const SkBitmap* bitmap)
: storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
internal::ImageRepSkia* rep = new internal::ImageRepSkia(
@@ -247,6 +238,13 @@ Image::Image(const SkBitmap& bitmap)
AddRepresentation(rep);
}
+Image::Image(const std::vector<const SkBitmap*>& bitmaps)
+ : storage_(new internal::ImageStorage(Image::kImageRepSkia)) {
+ internal::ImageRepSkia* rep = new internal::ImageRepSkia(
+ new ImageSkia(bitmaps));
+ AddRepresentation(rep);
+}
+
#if defined(TOOLKIT_GTK)
Image::Image(GdkPixbuf* pixbuf)
: storage_(new internal::ImageStorage(Image::kImageRepGdk)) {
@@ -276,7 +274,7 @@ Image::~Image() {
const SkBitmap* Image::ToSkBitmap() const {
internal::ImageRep* rep = GetRepresentation(Image::kImageRepSkia);
- return rep->AsImageRepSkia()->image()->bitmap();
+ return rep->AsImageRepSkia()->image()->bitmaps()[0];
}
const ImageSkia* Image::ToImageSkia() const {
@@ -303,10 +301,6 @@ NSImage* Image::ToNSImage() const {
}
#endif
-ImageSkia* Image::CopyImageSkia() const {
- return new ImageSkia(*ToImageSkia());
-}
-
SkBitmap* Image::CopySkBitmap() const {
return new SkBitmap(*ToSkBitmap());
}
@@ -392,8 +386,9 @@ internal::ImageRep* Image::GetRepresentation(
#elif defined(OS_MACOSX)
if (storage_->default_representation_type() == Image::kImageRepCocoa) {
internal::ImageRepCocoa* nsimage_rep = default_rep->AsImageRepCocoa();
- ImageSkia image_skia = internal::NSImageToImageSkia(nsimage_rep->image());
- rep = new internal::ImageRepSkia(new ImageSkia(image_skia));
+ std::vector<const SkBitmap*> bitmaps;
+ CHECK(internal::NSImageToSkBitmaps(nsimage_rep->image(), &bitmaps));
+ rep = new internal::ImageRepSkia(new ImageSkia(bitmaps));
}
#endif
CHECK(rep);
@@ -422,13 +417,13 @@ internal::ImageRep* Image::GetRepresentation(
#elif defined(TOOLKIT_GTK)
if (rep_type == Image::kImageRepGdk) {
GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(
- default_rep->AsImageRepSkia()->image()->bitmap());
+ default_rep->AsImageRepSkia()->image()->bitmaps()[0]);
native_rep = new internal::ImageRepGdk(pixbuf);
}
#elif defined(OS_MACOSX)
if (rep_type == Image::kImageRepCocoa) {
- NSImage* image = internal::ImageSkiaToNSImage(
- default_rep->AsImageRepSkia()->image());
+ NSImage* image = gfx::SkBitmapsToNSImage(
+ default_rep->AsImageRepSkia()->image()->bitmaps());
base::mac::NSObjectRetain(image);
native_rep = new internal::ImageRepCocoa(image);
}
diff --git a/ui/gfx/image/image.h b/ui/gfx/image/image.h
index b5bb3bf..9c0e6eb 100644
--- a/ui/gfx/image/image.h
+++ b/ui/gfx/image/image.h
@@ -62,9 +62,6 @@ class UI_EXPORT Image {
// Creates an empty image with no representations.
Image();
- // Creates a new image with the default representation.
- explicit Image(const ImageSkia& image);
-
// Creates a new image with the default representation. The object will take
// ownership of the image.
explicit Image(const SkBitmap* bitmap);
@@ -73,6 +70,10 @@ class UI_EXPORT Image {
// representation.
explicit Image(const SkBitmap& bitmap);
+ // To create an Image that supports multiple resolutions pass a vector
+ // of bitmaps, one for each resolution.
+ explicit Image(const std::vector<const SkBitmap*>& bitmaps);
+
#if defined(TOOLKIT_GTK)
// Does not increase |pixbuf|'s reference count; expects to take ownership.
explicit Image(GdkPixbuf* pixbuf);
@@ -111,7 +112,6 @@ class UI_EXPORT Image {
// backing pixels are shared amongst all copies (a fact of each of the
// converted representations, rather than a limitation imposed by Image) and
// so the result should be considered immutable.
- ImageSkia* CopyImageSkia() const;
SkBitmap* CopySkBitmap() const;
#if defined(TOOLKIT_GTK)
GdkPixbuf* CopyGdkPixbuf() const;
diff --git a/ui/gfx/image/image_mac.mm b/ui/gfx/image/image_mac.mm
index eeed857..55b4aa4 100644
--- a/ui/gfx/image/image_mac.mm
+++ b/ui/gfx/image/image_mac.mm
@@ -1,46 +1,25 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
#import <AppKit/AppKit.h>
-#import <vector>
-#include "base/memory/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/image/image_skia.h"
namespace gfx {
namespace internal {
-gfx::ImageSkia NSImageToImageSkia(NSImage* image) {
- gfx::ImageSkia image_skia;
+bool NSImageToSkBitmaps(NSImage* image, std::vector<const SkBitmap*>* bitmaps) {
for (NSImageRep* imageRep in [image representations]) {
- NSSize imageRepSize = [imageRep size];
- SkBitmap bitmap(gfx::NSImageRepToSkBitmap(imageRep, imageRepSize, false));
- if (!bitmap.isNull() && !bitmap.empty()) {
- float scaleFactor = imageRepSize.width / [image size].width;
- image_skia.AddBitmapForScale(bitmap, scaleFactor);
- }
+ scoped_ptr<SkBitmap> bitmap(new SkBitmap(
+ gfx::NSImageRepToSkBitmap(imageRep, [imageRep size], false)));
+ if (bitmap->isNull())
+ return false;
+ bitmaps->push_back(bitmap.release());
}
- return image_skia;
-}
-
-NSImage* ImageSkiaToNSImage(const gfx::ImageSkia* image_skia) {
- if (image_skia->empty())
- return nil;
-
- scoped_nsobject<NSImage> image([[NSImage alloc] init]);
-
- const std::vector<SkBitmap> bitmaps = image_skia->bitmaps();
- for (std::vector<SkBitmap>::const_iterator it = bitmaps.begin();
- it != bitmaps.end(); ++it) {
- [image addRepresentation:gfx::SkBitmapToNSBitmapImageRep(*it)];
- }
-
- [image setSize:NSMakeSize(image_skia->width(), image_skia->height())];
- return [image.release() autorelease];
+ return true;
}
} // namespace internal
diff --git a/ui/gfx/image/image_mac_unittest.mm b/ui/gfx/image/image_mac_unittest.mm
index 1de9c64..f0ed004 100644
--- a/ui/gfx/image/image_mac_unittest.mm
+++ b/ui/gfx/image/image_mac_unittest.mm
@@ -6,7 +6,6 @@
#include "base/logging.h"
#include "base/memory/scoped_nsobject.h"
-#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image.h"
@@ -32,61 +31,57 @@ class ImageMacTest : public testing::Test {
namespace gt = gfx::test;
-TEST_F(ImageMacTest, MultiResolutionNSImageToImageSkia) {
- const int width1x = 10;
- const int height1x = 12;
- const int width2x = 20;
- const int height2x = 24;
+TEST_F(ImageMacTest, MultiResolutionNSImageToSkBitmap) {
+ const int width1 = 10;
+ const int height1 = 12;
+ const int width2 = 20;
+ const int height2 = 24;
NSImageRep* image_rep_1;
- CreateBitmapImageRep(width1x, height1x, &image_rep_1);
+ CreateBitmapImageRep(width1, height1, &image_rep_1);
NSImageRep* image_rep_2;
- CreateBitmapImageRep(width2x, height2x, &image_rep_2);
+ CreateBitmapImageRep(width2, height2, &image_rep_2);
scoped_nsobject<NSImage> ns_image(
- [[NSImage alloc] initWithSize:NSMakeSize(width1x, height1x)]);
+ [[NSImage alloc] initWithSize:NSMakeSize(width1, height1)]);
[ns_image addRepresentation:image_rep_1];
[ns_image addRepresentation:image_rep_2];
gfx::Image image(ns_image.release());
EXPECT_EQ(1u, image.RepresentationCount());
-
- const gfx::ImageSkia* image_skia = image.ToImageSkia();
- EXPECT_EQ(2u, image_skia->bitmaps().size());
-
- float scale_factor;
- const SkBitmap& bitmap1x = image_skia->GetBitmapForScale(1.0f, 1.0f,
- &scale_factor);
- EXPECT_TRUE(!bitmap1x.isNull());
- EXPECT_EQ(1.0f, scale_factor);
- EXPECT_EQ(width1x, bitmap1x.width());
- EXPECT_EQ(height1x, bitmap1x.height());
-
- const SkBitmap& bitmap2x = image_skia->GetBitmapForScale(2.0f, 2.0f,
- &scale_factor);
- EXPECT_TRUE(!bitmap2x.isNull());
- EXPECT_EQ(2.0f, scale_factor);
- EXPECT_EQ(width2x, bitmap2x.width());
- EXPECT_EQ(height2x, bitmap2x.height());
+ const std::vector<const SkBitmap*>& bitmaps = image.ToImageSkia()->bitmaps();
+ EXPECT_EQ(2u, bitmaps.size());
+
+ const SkBitmap* bitmap1 = bitmaps[0];
+ EXPECT_TRUE(bitmap1);
+ const SkBitmap* bitmap2 = bitmaps[1];
+ EXPECT_TRUE(bitmap2);
+
+ if (bitmap1->width() == width1) {
+ EXPECT_EQ(bitmap1->height(), height1);
+ EXPECT_EQ(bitmap2->width(), width2);
+ EXPECT_EQ(bitmap2->height(), height2);
+ } else {
+ EXPECT_EQ(bitmap1->width(), width2);
+ EXPECT_EQ(bitmap1->height(), height2);
+ EXPECT_EQ(bitmap2->width(), width1);
+ EXPECT_EQ(bitmap2->height(), height1);
+ }
// ToImageSkia should create a second representation.
EXPECT_EQ(2u, image.RepresentationCount());
}
-TEST_F(ImageMacTest, MultiResolutionImageSkiaToNSImage) {
- const int width1x = 10;
- const int height1x= 12;
- const int width2x = 20;
- const int height2x = 24;
-
- scoped_ptr<SkBitmap> bitmap1x(gt::CreateBitmap(width1x, height1x));
- scoped_ptr<SkBitmap> bitmap2x(gt::CreateBitmap(width2x, height2x));
+TEST_F(ImageMacTest, MultiResolutionSkBitmapToNSImage) {
+ const int width1 = 10;
+ const int height1 = 12;
+ const int width2 = 20;
+ const int height2 = 24;
- gfx::ImageSkia image_skia;
- image_skia.AddBitmapForScale(*bitmap1x, 1.0f);
- image_skia.AddBitmapForScale(*bitmap2x, 2.0f);
-
- gfx::Image image(image_skia);
+ std::vector<const SkBitmap*> bitmaps;
+ bitmaps.push_back(gt::CreateBitmap(width1, height1));
+ bitmaps.push_back(gt::CreateBitmap(width2, height2));
+ gfx::Image image(bitmaps);
EXPECT_EQ(1u, image.RepresentationCount());
EXPECT_EQ(2u, image.ToImageSkia()->bitmaps().size());
@@ -94,24 +89,19 @@ TEST_F(ImageMacTest, MultiResolutionImageSkiaToNSImage) {
NSImage* ns_image = image;
EXPECT_TRUE(ns_image);
- // Image size should be the same as the 1x bitmap.
- EXPECT_EQ([ns_image size].width, width1x);
- EXPECT_EQ([ns_image size].height, height1x);
-
EXPECT_EQ(2u, [[image representations] count]);
NSImageRep* image_rep_1 = [[image representations] objectAtIndex:0];
NSImageRep* image_rep_2 = [[image representations] objectAtIndex:1];
- if ([image_rep_1 size].width == width1x) {
- EXPECT_EQ([image_rep_1 size].width, width1x);
- EXPECT_EQ([image_rep_1 size].height, height1x);
- EXPECT_EQ([image_rep_2 size].width, width2x);
- EXPECT_EQ([image_rep_2 size].height, height2x);
+ if ([image_rep_1 size].width == width1) {
+ EXPECT_EQ([image_rep_1 size].height, height1);
+ EXPECT_EQ([image_rep_2 size].width, width2);
+ EXPECT_EQ([image_rep_2 size].height, height2);
} else {
- EXPECT_EQ([image_rep_1 size].width, width2x);
- EXPECT_EQ([image_rep_1 size].height, height2x);
- EXPECT_EQ([image_rep_2 size].width, width1x);
- EXPECT_EQ([image_rep_2 size].height, height1x);
+ EXPECT_EQ([image_rep_1 size].width, width2);
+ EXPECT_EQ([image_rep_1 size].height, height2);
+ EXPECT_EQ([image_rep_2 size].width, width1);
+ EXPECT_EQ([image_rep_2 size].height, height1);
}
// Cast to NSImage* should create a second representation.
diff --git a/ui/gfx/image/image_skia.cc b/ui/gfx/image/image_skia.cc
index d7ad469c..3c2e94f 100644
--- a/ui/gfx/image/image_skia.cc
+++ b/ui/gfx/image/image_skia.cc
@@ -8,200 +8,139 @@
#include <cmath>
#include "base/logging.h"
-#include "ui/gfx/size.h"
-#include "base/message_loop.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
+#include "base/stl_util.h"
namespace gfx {
-namespace internal {
-
-// A helper class such that ImageSkia can be cheaply copied. ImageSkia holds a
-// refptr instance of ImageSkiaStorage, which in turn holds all of ImageSkia's
-// information.
-class ImageSkiaStorage : public base::RefCounted<ImageSkiaStorage> {
- public:
- ImageSkiaStorage() {
- }
-
- void AddBitmap(const SkBitmap& bitmap) {
- bitmaps_.push_back(bitmap);
- }
-
- const std::vector<SkBitmap>& bitmaps() const { return bitmaps_; }
-
- void set_size(const gfx::Size& size) { size_ = size; }
- const gfx::Size& size() const { return size_; }
-
- private:
- ~ImageSkiaStorage() {
+ImageSkia::ImageSkia(const SkBitmap* bitmap)
+ : size_(bitmap->width(), bitmap->height()),
+ mip_map_build_pending_(false) {
+ CHECK(bitmap);
+ // TODO(pkotwicz): Add a CHECK to ensure that !bitmap->isNull()
+ bitmaps_.push_back(bitmap);
+}
+
+ImageSkia::ImageSkia(const std::vector<const SkBitmap*>& bitmaps)
+ : bitmaps_(bitmaps),
+ mip_map_build_pending_(false) {
+ CHECK(!bitmaps_.empty());
+ // TODO(pkotwicz): Add a CHECK to ensure that !bitmap->isNull() for each
+ // vector element.
+ // Assume that the smallest bitmap represents 1x scale factor.
+ for (size_t i = 0; i < bitmaps_.size(); ++i) {
+ gfx::Size bitmap_size(bitmaps_[i]->width(), bitmaps_[i]->height());
+ if (size_.IsEmpty() || bitmap_size.GetArea() < size_.GetArea())
+ size_ = bitmap_size;
}
+}
- // Bitmaps at different densities.
- std::vector<SkBitmap> bitmaps_;
-
- // Size of the image in DIP.
- gfx::Size size_;
-
- friend class base::RefCounted<ImageSkiaStorage>;
-};
-
-} // internal
-
-ImageSkia::ImageSkia() : storage_(NULL) {
+ImageSkia::~ImageSkia() {
+ STLDeleteElements(&bitmaps_);
}
-ImageSkia::ImageSkia(const SkBitmap& bitmap) {
- Init(bitmap);
+void ImageSkia::BuildMipMap() {
+ mip_map_build_pending_ = true;
}
-ImageSkia::ImageSkia(const SkBitmap& bitmap, float dip_scale_factor) {
- Init(bitmap, dip_scale_factor);
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, int x, int y) {
+ SkPaint p;
+ DrawToCanvasInt(canvas, x, y, p);
}
-ImageSkia::ImageSkia(const SkBitmap* bitmap) {
- Init(*bitmap);
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas,
+ int x, int y,
+ const SkPaint& paint) {
+
+ if (IsZeroSized())
+ return;
+
+ SkMatrix m = canvas->sk_canvas()->getTotalMatrix();
+ float scale_x = std::abs(SkScalarToFloat(m.getScaleX()));
+ float scale_y = std::abs(SkScalarToFloat(m.getScaleY()));
+
+ const SkBitmap* bitmap = GetBitmapForScale(scale_x, scale_y);
- if (MessageLoop::current()) {
- // Use DeleteSoon such that |bitmap| is still valid if caller uses |bitmap|
- // immediately after having called constructor.
- MessageLoop::current()->DeleteSoon(FROM_HERE, bitmap);
- } else {
- // Hit in unittests.
- delete bitmap;
+ if (mip_map_build_pending_) {
+ const_cast<SkBitmap*>(bitmap)->buildMipMap();
+ mip_map_build_pending_ = false;
}
-}
-ImageSkia::ImageSkia(const ImageSkia& other) : storage_(other.storage_) {
-}
+ float bitmap_scale_x = static_cast<float>(bitmap->width()) / width();
+ float bitmap_scale_y = static_cast<float>(bitmap->height()) / height();
-ImageSkia& ImageSkia::operator=(const ImageSkia& other) {
- storage_ = other.storage_;
- return *this;
+ canvas->Save();
+ canvas->sk_canvas()->scale(1.0f / bitmap_scale_x,
+ 1.0f / bitmap_scale_y);
+ canvas->sk_canvas()->drawBitmap(*bitmap, SkFloatToScalar(x * bitmap_scale_x),
+ SkFloatToScalar(y * bitmap_scale_y));
+ canvas->Restore();
}
-ImageSkia& ImageSkia::operator=(const SkBitmap& other) {
- Init(other);
- return *this;
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas,
+ int src_x, int src_y, int src_w, int src_h,
+ int dest_x, int dest_y, int dest_w, int dest_h,
+ bool filter) {
+ SkPaint p;
+ DrawToCanvasInt(canvas, src_x, src_y, src_w, src_h, dest_x, dest_y,
+ dest_w, dest_h, filter, p);
}
-ImageSkia::operator SkBitmap&() const {
- if (isNull()) {
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
- // Static null bitmap such that we are not returning a temporary.
- static SkBitmap* null_bitmap = new SkBitmap();
- return *null_bitmap;
- }
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas,
+ int src_x, int src_y, int src_w, int src_h,
+ int dest_x, int dest_y, int dest_w, int dest_h,
+ bool filter,
+ const SkPaint& paint) {
+ if (IsZeroSized())
+ return;
- return const_cast<SkBitmap&>(storage_->bitmaps()[0]);
-}
+ SkMatrix m = canvas->sk_canvas()->getTotalMatrix();
+ float scale_x = std::abs(SkScalarToFloat(m.getScaleX()));
+ float scale_y = std::abs(SkScalarToFloat(m.getScaleY()));
-ImageSkia::~ImageSkia() {
-}
+ const SkBitmap* bitmap = GetBitmapForScale(scale_x, scale_y);
-void ImageSkia::AddBitmapForScale(const SkBitmap& bitmap,
- float dip_scale_factor) {
- DCHECK(!bitmap.isNull());
-
- if (isNull()) {
- Init(bitmap, dip_scale_factor);
- } else {
- // We currently assume that the bitmap size = 1x size * |dip_scale_factor|.
- // TODO(pkotwicz): Do something better because of rounding errors when
- // |dip_scale_factor| is not an int.
- // TODO(pkotwicz): Remove DCHECK for dip_scale_factor == 1.0f once
- // image_loading_tracker correctly handles multiple sized images.
- DCHECK(dip_scale_factor == 1.0f ||
- static_cast<int>(width() * dip_scale_factor) == bitmap.width());
- DCHECK(dip_scale_factor == 1.0f ||
- static_cast<int>(height() * dip_scale_factor) == bitmap.height());
- storage_->AddBitmap(bitmap);
+ if (mip_map_build_pending_) {
+ const_cast<SkBitmap*>(bitmap)->buildMipMap();
+ mip_map_build_pending_ = false;
}
-}
-const SkBitmap& ImageSkia::GetBitmapForScale(float x_scale_factor,
- float y_scale_factor,
- float* bitmap_scale_factor) const {
+ float bitmap_scale_x = static_cast<float>(bitmap->width()) / width();
+ float bitmap_scale_y = static_cast<float>(bitmap->height()) / height();
- // Static null bitmap such that we are not returning a temporary.
- static SkBitmap* null_bitmap = new SkBitmap();
+ canvas->Save();
+ canvas->sk_canvas()->scale(1.0f / bitmap_scale_x,
+ 1.0f / bitmap_scale_y);
+ canvas->DrawBitmapFloat(*bitmap,
+ src_x * bitmap_scale_x, src_y * bitmap_scale_x,
+ src_w * bitmap_scale_x, src_h * bitmap_scale_y,
+ dest_x * bitmap_scale_x, dest_y * bitmap_scale_y,
+ dest_w * bitmap_scale_x, dest_h * bitmap_scale_y,
+ filter, paint);
- if (empty())
- return *null_bitmap;
+ canvas->Restore();
+}
+const SkBitmap* ImageSkia::GetBitmapForScale(float x_scale_factor,
+ float y_scale_factor) const {
// Get the desired bitmap width and height given |x_scale_factor|,
- // |y_scale_factor| and size at 1x density.
- float desired_width = width() * x_scale_factor;
- float desired_height = height() * y_scale_factor;
+ // |y_scale_factor| and |size_| at 1x density.
+ float desired_width = size_.width() * x_scale_factor;
+ float desired_height = size_.height() * y_scale_factor;
- const std::vector<SkBitmap>& bitmaps = storage_->bitmaps();
size_t closest_index = 0;
float smallest_diff = std::numeric_limits<float>::max();
- for (size_t i = 0; i < bitmaps.size(); ++i) {
- float diff = std::abs(bitmaps[i].width() - desired_width) +
- std::abs(bitmaps[i].height() - desired_height);
+ for (size_t i = 0; i < bitmaps_.size(); ++i) {
+ if (bitmaps_[i]->isNull())
+ continue;
+
+ float diff = std::abs(bitmaps_[i]->width() - desired_width) +
+ std::abs(bitmaps_[i]->height() - desired_height);
if (diff < smallest_diff) {
closest_index = i;
smallest_diff = diff;
}
}
- if (smallest_diff < std::numeric_limits<float>::max()) {
- *bitmap_scale_factor = bitmaps[closest_index].width() / width();
- return bitmaps[closest_index];
- }
-
- return *null_bitmap;
-}
-
-bool ImageSkia::empty() const {
- return isNull() || storage_->size().IsEmpty();
-}
-
-int ImageSkia::width() const {
- return isNull() ? 0 : storage_->size().width();
-}
-
-int ImageSkia::height() const {
- return isNull() ? 0 : storage_->size().height();
-}
-
-bool ImageSkia::extractSubset(ImageSkia* dst, SkIRect& subset) const {
- if (isNull())
- return false;
- SkBitmap dst_bitmap;
- bool return_value = storage_->bitmaps()[0].extractSubset(&dst_bitmap,
- subset);
- *dst = ImageSkia(dst_bitmap);
- return return_value;
-}
-
-const std::vector<SkBitmap> ImageSkia::bitmaps() const {
- return storage_->bitmaps();
-}
-
-const SkBitmap* ImageSkia::bitmap() const {
- if (isNull())
- return NULL;
-
- return &storage_->bitmaps()[0];
-}
-
-void ImageSkia::Init(const SkBitmap& bitmap) {
- Init(bitmap, 1.0f);
-}
-
-void ImageSkia::Init(const SkBitmap& bitmap, float scale_factor) {
- DCHECK_GT(scale_factor, 0.0f);
- // TODO(pkotwicz): The image should be null whenever bitmap is null.
- if (bitmap.empty()) {
- storage_ = NULL;
- return;
- }
- storage_ = new internal::ImageSkiaStorage();
- storage_->set_size(gfx::Size(static_cast<int>(bitmap.width() / scale_factor),
- static_cast<int>(bitmap.height() / scale_factor)));
- storage_->AddBitmap(bitmap);
+ return bitmaps_[closest_index];
}
} // namespace gfx
diff --git a/ui/gfx/image/image_skia.h b/ui/gfx/image/image_skia.h
index 8b911cb..bdfb53f 100644
--- a/ui/gfx/image/image_skia.h
+++ b/ui/gfx/image/image_skia.h
@@ -9,119 +9,80 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/ui_export.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/size.h"
namespace gfx {
-namespace internal {
-class ImageSkiaStorage;
-} // namespace internal
-
// Container for the same image at different densities, similar to NSImage.
-// Image height and width are in DIP (Device Indepent Pixel) coordinates.
-//
-// ImageSkia should be used whenever possible instead of SkBitmap.
-// Functions that mutate the image should operate on the SkBitmap returned
-// from ImageSkia::GetBitmapForScale, not on ImageSkia.
-//
-// ImageSkia is cheap to copy and intentionally supports copy semantics.
+// Smallest image is assumed to represent 1x density.
+
+// ImageSkia should be used for caching and drawing images of different
+// densities. It should not be used as an SkBitmap wrapper.
class UI_EXPORT ImageSkia {
public:
- // Creates instance with no bitmaps.
- ImageSkia();
-
- // Adds ref to passed in bitmap.
- // DIP width and height are set based on scale factor of 1x.
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
- ImageSkia(const SkBitmap& bitmap);
-
- // Adds ref to passed in bitmap.
- // DIP width and height are set based on |dip_scale_factor|.
- ImageSkia(const SkBitmap& bitmap, float dip_scale_factor);
-
- // Takes ownership of passed in bitmap.
- // Caller should not assume that |bitmap| will be valid after constructor
- // is called.
- // DIP width and height are set based on scale factor of 1x.
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
explicit ImageSkia(const SkBitmap* bitmap);
-
- // Copies a reference to |other|'s storage.
- ImageSkia(const ImageSkia& other);
-
- // Copies a reference to |other|'s storage.
- ImageSkia& operator=(const ImageSkia& other);
-
- // Converts from SkBitmap.
- // Adds ref to passed in bitmap.
- // DIP width and height are set based on scale factor of 1x.
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
- ImageSkia& operator=(const SkBitmap& other);
-
- // Converts to SkBitmap.
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
- operator SkBitmap&() const;
-
+ explicit ImageSkia(const std::vector<const SkBitmap*>& bitmaps);
~ImageSkia();
- // Adds |bitmap| for |dip_scale_factor| to bitmaps contained by this object.
- // Adds ref to passed in bitmap.
- // DIP width and height are set based on |dip_scale_factor|.
- void AddBitmapForScale(const SkBitmap& bitmap, float dip_scale_factor);
-
- // Returns the bitmap whose density best matches |x_scale_factor| and
- // |y_scale_factor|.
- // Returns a null bitmap if object contains no bitmaps.
- // |bitmap_scale_factor| is set to the scale factor of the returned bitmap.
- const SkBitmap& GetBitmapForScale(float x_scale_factor,
- float y_scale_factor,
- float* bitmap_scale_factor) const;
-
- // Returns true if object is null or |size_| is empty.
- bool empty() const;
-
- // Returns true if this is a null object.
- // TODO(pkotwicz): Merge this function into empty().
- bool isNull() const { return storage_ == NULL; }
+ // Build mipmap at time of next call to |DrawToCanvasInt|.
+ void BuildMipMap();
+
+ // Draws the image with the origin at the specified location. The upper left
+ // corner of the image is rendered at the specified location.
+ void DrawToCanvasInt(Canvas* canvas, int x, int y);
+
+ // Draws the image with the origin at the specified location, using the
+ // specified paint. The upper left corner of the image is rendered at the
+ // specified location.
+ void DrawToCanvasInt(Canvas* canvas,
+ int x, int y,
+ const SkPaint& paint);
+
+ // Draws a portion of the image in the specified location. The src parameters
+ // correspond to the region of the image to draw in the region defined
+ // by the dest coordinates.
+ //
+ // If the width or height of the source differs from that of the destination,
+ // the image will be scaled. When scaling down, it is highly recommended
+ // that you call BuildMipMap() on your image to ensure that it has
+ // a mipmap, which will result in much higher-quality output. Set |filter| to
+ // use filtering for bitmaps, otherwise the nearest-neighbor algorithm is used
+ // for resampling.
+ //
+ // An optional custom SkPaint can be provided.
+ void DrawToCanvasInt(Canvas* canvas,
+ int src_x, int src_y, int src_w, int src_h,
+ int dest_x, int dest_y, int dest_w, int dest_h,
+ bool filter);
+ void DrawToCanvasInt(Canvas* canvas,
+ int src_x, int src_y, int src_w, int src_h,
+ int dest_x, int dest_y, int dest_w, int dest_h,
+ bool filter,
+ const SkPaint& paint);
+
+ // Returns true if |size_| is empty.
+ bool IsZeroSized() const { return size_.IsEmpty(); }
// Width and height of image in DIP coordinate system.
- int width() const;
- int height() const;
-
- // Wrapper function for SkBitmap::extractBitmap.
- // Operates on bitmap at index 0 if available.
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
- bool extractSubset(ImageSkia* dst, SkIRect& subset) const;
-
- // Returns pointer to an SkBitmap contained by this object.
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
- const SkBitmap* bitmap() const;
+ int width() const { return size_.width(); }
+ int height() const { return size_.height(); }
// Returns a vector with the SkBitmaps contained in this object.
- const std::vector<SkBitmap> bitmaps() const;
+ const std::vector<const SkBitmap*>& bitmaps() const { return bitmaps_; }
private:
- // Initialize ImageStorage with passed in parameters.
- // If |bitmap.isNull()|, ImageStorage is set to NULL.
- // Scale factor is set based on default scale factor of 1x.
- // TODO(pkotwicz): This is temporary till conversion to gfx::ImageSkia is
- // done.
- void Init(const SkBitmap& bitmap);
-
- // Initialize ImageStorage with passed in parameters.
- // If |bitmap.isNull()|, ImageStorage is set to NULL.
- void Init(const SkBitmap& bitmap, float scale_factor);
-
- // A refptr so that ImageRepSkia can be copied cheaply.
- scoped_refptr<internal::ImageSkiaStorage> storage_;
+ // Returns the bitmap whose density best matches |x_scale_factor| and
+ // |y_scale_factor|.
+ const SkBitmap* GetBitmapForScale(float x_scale_factor,
+ float y_scale_factor) const;
+
+ std::vector<const SkBitmap*> bitmaps_;
+ gfx::Size size_;
+ bool mip_map_build_pending_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageSkia);
};
} // namespace gfx
diff --git a/ui/gfx/image/image_unittest.cc b/ui/gfx/image/image_unittest.cc
index 7b50be8..8793562 100644
--- a/ui/gfx/image/image_unittest.cc
+++ b/ui/gfx/image/image_unittest.cc
@@ -251,39 +251,41 @@ TEST_F(ImageTest, Assign) {
EXPECT_EQ(image1.ToSkBitmap(), image2.ToSkBitmap());
}
-TEST_F(ImageTest, MultiResolutionImage) {
- const int width1x = 10;
- const int height1x = 12;
- const int width2x = 20;
- const int height2x = 24;
-
- scoped_ptr<SkBitmap> bitmap1(gt::CreateBitmap(width1x, height1x));
- scoped_ptr<SkBitmap> bitmap2(gt::CreateBitmap(width2x, height2x));
-
- gfx::ImageSkia image_skia;
- image_skia.AddBitmapForScale(*bitmap1, 1.0f);
- image_skia.AddBitmapForScale(*bitmap2, 2.0f);
-
- EXPECT_EQ(2u, image_skia.bitmaps().size());
-
- float scale_factor;
- const SkBitmap& bitmap1x = image_skia.GetBitmapForScale(1.0f, 1.0f,
- &scale_factor);
- EXPECT_TRUE(!bitmap1x.isNull());
- EXPECT_EQ(1.0f, scale_factor);
- EXPECT_EQ(width1x, bitmap1x.width());
- EXPECT_EQ(height1x, bitmap1x.height());
-
- const SkBitmap& bitmap2x = image_skia.GetBitmapForScale(2.0f, 2.0f,
- &scale_factor);
- EXPECT_TRUE(!bitmap2x.isNull());
- EXPECT_EQ(2.0f, scale_factor);
- EXPECT_EQ(width2x, bitmap2x.width());
- EXPECT_EQ(height2x, bitmap2x.height());
-
- // Check that the image has a single representation.
- gfx::Image image(image_skia);
+TEST_F(ImageTest, MultiResolutionSkBitmap) {
+ const int width1 = 10;
+ const int height1 = 12;
+ const int width2 = 20;
+ const int height2 = 24;
+
+ std::vector<const SkBitmap*> bitmaps;
+ bitmaps.push_back(gt::CreateBitmap(width1, height1));
+ bitmaps.push_back(gt::CreateBitmap(width2, height2));
+ gfx::Image image(bitmaps);
+
+ EXPECT_EQ(1u, image.RepresentationCount());
+ const std::vector<const SkBitmap*>& image_bitmaps =
+ image.ToImageSkia()->bitmaps();
+ EXPECT_EQ(2u, image_bitmaps.size());
+
+ const SkBitmap* bitmap1 = image_bitmaps[0];
+ EXPECT_TRUE(bitmap1);
+ const SkBitmap* bitmap2 = image_bitmaps[1];
+ EXPECT_TRUE(bitmap2);
+
+ if (bitmap1->width() == width1) {
+ EXPECT_EQ(bitmap1->height(), height1);
+ EXPECT_EQ(bitmap2->width(), width2);
+ EXPECT_EQ(bitmap2->height(), height2);
+ } else {
+ EXPECT_EQ(bitmap1->width(), width2);
+ EXPECT_EQ(bitmap1->height(), height2);
+ EXPECT_EQ(bitmap2->width(), width1);
+ EXPECT_EQ(bitmap2->height(), height1);
+ }
+
+ // Sanity check.
EXPECT_EQ(1u, image.RepresentationCount());
+ EXPECT_EQ(2u, image.ToImageSkia()->bitmaps().size());
}
// Integration tests with UI toolkit frameworks require linking against the