Commit 67345682 authored by oshima@chromium.org's avatar oshima@chromium.org

Add ImageSkiaRep::unscaled that tells if the image is for unscaled image.

 Unscaled image only contains 1.0f image and used when it is the client responsibility to scale the image properly (Wallpaper for example)

 This is required for https://codereview.chromium.org/263253003/

BUG=None
TEST=covered by unit test

Review URL: https://codereview.chromium.org/277773002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269660 0039d316-1c4b-4281-b951-d872f2087c98
parent 28ea1d80
......@@ -105,6 +105,13 @@ class ResourceBundle::ResourceBundleImageSource : public gfx::ImageSkiaSource {
ScaleFactor scale_factor = GetSupportedScaleFactor(scale);
bool found = rb_->LoadBitmap(resource_id_, &scale_factor,
&image, &fell_back_to_1x);
// If the resource is in the package with SCALE_FACTOR_NONE, it
// can be used in any scale factor. The image is maked as "unscaled"
// so that the ImageSkia do not automatically scale.
bool unscaled = scale_factor == ui::SCALE_FACTOR_NONE;
if (unscaled)
scale_factor = ui::SCALE_FACTOR_100P;
if (!found)
return gfx::ImageSkiaRep();
......@@ -115,12 +122,12 @@ class ResourceBundle::ResourceBundleImageSource : public gfx::ImageSkiaSource {
skia::ImageOperations::RESIZE_LANCZOS3,
gfx::ToCeiledInt(image.width() * scale),
gfx::ToCeiledInt(image.height() * scale));
} else {
} else if (!unscaled) {
image = PlatformScaleImage(image,
ui::GetScaleForScaleFactor(scale_factor),
scale);
}
return gfx::ImageSkiaRep(image, scale);
return gfx::ImageSkiaRep(image, unscaled ? 0.0f : scale);
}
private:
......@@ -728,13 +735,10 @@ bool ResourceBundle::LoadBitmap(int resource_id,
bool* fell_back_to_1x) const {
DCHECK(fell_back_to_1x);
for (size_t i = 0; i < data_packs_.size(); ++i) {
// If the resource is in the package with SCALE_FACTOR_NONE, it
// can be used in any scale factor, but set 100P in ImageSkia so
// that it will be scaled property.
if (data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_NONE &&
LoadBitmap(*data_packs_[i], resource_id, bitmap, fell_back_to_1x)) {
*scale_factor = ui::SCALE_FACTOR_100P;
DCHECK(!*fell_back_to_1x);
*scale_factor = ui::SCALE_FACTOR_NONE;
return true;
}
if (data_packs_[i]->GetScaleFactor() == *scale_factor &&
......
......@@ -579,6 +579,7 @@ TEST_F(ResourceBundleImageTest, MAYBE_FallbackToNone) {
gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
EXPECT_EQ(1u, image_skia->image_reps().size());
EXPECT_TRUE(image_skia->image_reps()[0].unscaled());
EXPECT_EQ(ui::SCALE_FACTOR_100P,
GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
}
......
......@@ -102,6 +102,24 @@ class ImageSkiaStorage : public base::RefCountedThreadSafe<ImageSkiaStorage>,
return (read_only_ && !source_.get()) || CalledOnValidThread();
}
// Add a new representation. This checks if the scale of the added image
// is not 1.0f, and mark the existing rep as scaled to make
// the image high DPI aware.
void AddRepresentation(const ImageSkiaRep& image) {
if (image.scale() != 1.0f) {
for (ImageSkia::ImageSkiaReps::iterator it = image_reps_.begin();
it < image_reps_.end();
++it) {
if (it->unscaled()) {
DCHECK_EQ(1.0f, it->scale());
it->SetScaled();
break;
}
}
}
image_reps_.push_back(image);
}
// Returns the iterator of the image rep whose density best matches
// |scale|. If the image for the |scale| doesn't exist in the storage and
// |storage| is set, it fetches new image by calling
......@@ -240,7 +258,7 @@ float ImageSkia::GetMaxSupportedScale() {
// static
ImageSkia ImageSkia::CreateFrom1xBitmap(const SkBitmap& bitmap) {
return ImageSkia(ImageSkiaRep(bitmap, 1.0f));
return ImageSkia(ImageSkiaRep(bitmap, 0.0f));
}
scoped_ptr<ImageSkia> ImageSkia::DeepCopy() const {
......@@ -278,7 +296,9 @@ void ImageSkia::AddRepresentation(const ImageSkiaRep& image_rep) {
Init(image_rep);
} else {
CHECK(CanModify());
storage_->image_reps().push_back(image_rep);
// If someone is adding ImageSkia explicitly, check if we should
// make the image high DPI aware.
storage_->AddRepresentation(image_rep);
}
}
......
......@@ -4,9 +4,11 @@
#include "ui/gfx/image/image_skia_rep.h"
#include "base/logging.h"
namespace gfx {
ImageSkiaRep::ImageSkiaRep() : scale_(1.0f) {
ImageSkiaRep::ImageSkiaRep() : scale_(0.0f) {
}
ImageSkiaRep::~ImageSkiaRep() {
......@@ -14,8 +16,8 @@ ImageSkiaRep::~ImageSkiaRep() {
ImageSkiaRep::ImageSkiaRep(const gfx::Size& size, float scale) : scale_(scale) {
bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
static_cast<int>(size.width() * scale),
static_cast<int>(size.height() * scale));
static_cast<int>(size.width() * this->scale()),
static_cast<int>(size.height() * this->scale()));
bitmap_.allocPixels();
}
......@@ -25,11 +27,17 @@ ImageSkiaRep::ImageSkiaRep(const SkBitmap& src, float scale)
}
int ImageSkiaRep::GetWidth() const {
return static_cast<int>(bitmap_.width() / scale_);
return static_cast<int>(bitmap_.width() / scale());
}
int ImageSkiaRep::GetHeight() const {
return static_cast<int>(bitmap_.height() / scale_);
return static_cast<int>(bitmap_.height() / scale());
}
void ImageSkiaRep::SetScaled() {
DCHECK_EQ(0.0f, scale_);
if (scale_ == 0.0f)
scale_ = 1.0f;
}
} // namespace gfx
......@@ -12,6 +12,8 @@
namespace gfx {
// An ImageSkiaRep represents a bitmap and the scale factor it is intended for.
// 0.0f scale is used to indicate that this ImageSkiaRep is used for unscaled
// image (the image that only returns 1.0f scale image).
class GFX_EXPORT ImageSkiaRep {
public:
// Create null bitmap.
......@@ -19,7 +21,9 @@ class GFX_EXPORT ImageSkiaRep {
~ImageSkiaRep();
// Creates a bitmap with kARGB_8888_Config config with given |size| in DIP.
// This allocates pixels in the bitmap.
// This allocates pixels in the bitmap. Specifying 0 scale means the image
// is for unscaled image. (unscaled() returns truen, and scale() returns
// 1.0f;)
ImageSkiaRep(const gfx::Size& size, float scale);
// Creates a bitmap with given scale.
......@@ -41,7 +45,12 @@ class GFX_EXPORT ImageSkiaRep {
}
// Retrieves the scale that the bitmap will be painted at.
float scale() const { return scale_; }
float scale() const { return unscaled() ? 1.0f : scale_; }
bool unscaled() const { return scale_ == 0.0f; }
// Mark the image to be used as scaled image.
void SetScaled();
// Returns backing bitmap.
const SkBitmap& sk_bitmap() const { return bitmap_; }
......@@ -51,6 +60,7 @@ class GFX_EXPORT ImageSkiaRep {
SkBitmap& mutable_sk_bitmap() { return bitmap_; }
SkBitmap bitmap_;
float scale_;
};
......
......@@ -375,4 +375,19 @@ TEST(ImageSkiaTest, SourceOnThreadTest) {
// Just in case we ever get lumped together with other compilation units.
#undef ENABLE_NON_THREAD_SAFE
TEST(ImageSkiaTest, Unscaled) {
SkBitmap bitmap;
// An ImageSkia created with 1x bitmap is unscaled.
ImageSkia image_skia = ImageSkia::CreateFrom1xBitmap(bitmap);
EXPECT_TRUE(image_skia.GetRepresentation(1.0f).unscaled());
ImageSkiaRep rep_2x(Size(100, 100), 2.0f);
// When reps for other scales are added, the unscaled image
// becomes scaled.
image_skia.AddRepresentation(rep_2x);
EXPECT_FALSE(image_skia.GetRepresentation(1.0f).unscaled());
EXPECT_FALSE(image_skia.GetRepresentation(2.0f).unscaled());
}
} // namespace gfx
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment