| Index: ui/base/resource/resource_bundle.cc
|
| diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc
|
| index 14cf974c3defee73ee632e1eb6698b85d6396205..9c3b39268b43a174ad96bc1d53685cc9df8763b2 100644
|
| --- a/ui/base/resource/resource_bundle.cc
|
| +++ b/ui/base/resource/resource_bundle.cc
|
| @@ -27,6 +27,7 @@
|
| #include "ui/gfx/codec/jpeg_codec.h"
|
| #include "ui/gfx/codec/png_codec.h"
|
| #include "ui/gfx/image/image_skia.h"
|
| +#include "ui/gfx/image/image_skia_source.h"
|
| #include "ui/gfx/screen.h"
|
| #include "ui/gfx/skbitmap_operations.h"
|
|
|
| @@ -39,6 +40,8 @@ const int kSmallFontSizeDelta = -2;
|
| const int kMediumFontSizeDelta = 3;
|
| const int kLargeFontSizeDelta = 8;
|
|
|
| +ResourceBundle* g_shared_instance_ = NULL;
|
| +
|
| // Returns the actual scale factor of |bitmap| given the image representations
|
| // which have already been added to |image|.
|
| // TODO(pkotwicz): Remove this once we are no longer loading 1x resources
|
| @@ -53,41 +56,88 @@ ui::ScaleFactor GetActualScaleFactor(const gfx::ImageSkia& image,
|
| static_cast<float>(bitmap.width()) / image.width());
|
| }
|
|
|
| -// If 2x resource is missing from |image| or is the incorrect size,
|
| -// logs the resource id and creates a 2x version of the resource.
|
| -// Blends the created resource with red to make it distinguishable from
|
| -// bitmaps in the resource pak.
|
| -void Create2xResourceIfMissing(gfx::ImageSkia image, int idr) {
|
| - CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| - if (command_line->HasSwitch(
|
| - switches::kHighlightMissing2xResources) &&
|
| - !image.HasRepresentation(ui::SCALE_FACTOR_200P)) {
|
| - gfx::ImageSkiaRep image_rep = image.GetRepresentation(SCALE_FACTOR_200P);
|
| -
|
| - if (image_rep.scale_factor() == ui::SCALE_FACTOR_100P)
|
| - LOG(INFO) << "Missing 2x resource with id " << idr;
|
| - else
|
| - LOG(INFO) << "Incorrectly sized 2x resource with id " << idr;
|
| -
|
| - SkBitmap bitmap2x = skia::ImageOperations::Resize(image_rep.sk_bitmap(),
|
| - skia::ImageOperations::RESIZE_LANCZOS3,
|
| - image.width() * 2, image.height() * 2);
|
| -
|
| - SkBitmap mask;
|
| - mask.setConfig(SkBitmap::kARGB_8888_Config,
|
| - bitmap2x.width(),
|
| - bitmap2x.height());
|
| - mask.allocPixels();
|
| - mask.eraseColor(SK_ColorRED);
|
| - SkBitmap result = SkBitmapOperations::CreateBlendedBitmap(bitmap2x, mask,
|
| - 0.2);
|
| - image.AddRepresentation(gfx::ImageSkiaRep(result, SCALE_FACTOR_200P));
|
| - }
|
| +bool ShouldHighlightMissing2xResources() {
|
| + return CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kHighlightMissing2xResources);
|
| }
|
|
|
| } // namespace
|
|
|
| -ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;
|
| +// An ImageSkiaSource that loads bitmaps for given scale factor from
|
| +// ResourceBundle on demand for given resource_id. It falls back
|
| +// to 100P image if corresponding 200P image doesn't exist.
|
| +// If 200P image does not have 2x size of 100P images, it will end up
|
| +// with broken UI because it will be drawn as if it has 2x size.
|
| +// When --highlight-missing-2x-resources flag is specified, it
|
| +// will show the scaled image blended with red instead.
|
| +class ResourceBundle::ResourceBundleImageSource : public gfx::ImageSkiaSource {
|
| + public:
|
| + ResourceBundleImageSource(int resource_id, const gfx::Size& size_in_dip)
|
| + : resource_id_(resource_id),
|
| + size_in_dip_(size_in_dip) {
|
| + }
|
| + virtual ~ResourceBundleImageSource() {}
|
| +
|
| + // gfx::ImageSkiaSource overrides:
|
| + virtual gfx::ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) {
|
| + ResourceBundle& rb = ResourceBundle::GetSharedInstance();
|
| +
|
| + scoped_ptr<SkBitmap> result(rb.LoadBitmap(resource_id_, scale_factor));
|
| + gfx::Size size_in_pixel =
|
| + size_in_dip_.Scale(ui::GetScaleFactorScale(scale_factor));
|
| +
|
| + if (scale_factor == SCALE_FACTOR_200P &&
|
| + (!result.get() ||
|
| + result->width() != size_in_pixel.width() ||
|
| + result->height() != size_in_pixel.height())) {
|
| +
|
| + // If 2x resource is missing from |image| or is the incorrect
|
| + // size and --highlight-missing-2x-resources is specified, logs
|
| + // the resource id and creates a 2x version of the resource.
|
| + // Blends the created resource with red to make it
|
| + // distinguishable from bitmaps in the resource pak.
|
| + if (ShouldHighlightMissing2xResources()) {
|
| + if (!result.get())
|
| + LOG(ERROR) << "Missing 2x resource. id=" << resource_id_;
|
| + else
|
| + LOG(ERROR) << "Incorrectly sized 2x resource. id=" << resource_id_;
|
| +
|
| + SkBitmap bitmap1x = *(rb.LoadBitmap(resource_id_, SCALE_FACTOR_100P));
|
| + SkBitmap bitmap2x = skia::ImageOperations::Resize(
|
| + bitmap1x,
|
| + skia::ImageOperations::RESIZE_LANCZOS3,
|
| + bitmap1x.width() * 2, bitmap1x.height() * 2);
|
| +
|
| + SkBitmap mask;
|
| + mask.setConfig(SkBitmap::kARGB_8888_Config,
|
| + bitmap2x.width(),
|
| + bitmap2x.height());
|
| + mask.allocPixels();
|
| + mask.eraseColor(SK_ColorRED);
|
| + result.reset(new SkBitmap());
|
| + *result.get() = SkBitmapOperations::CreateBlendedBitmap(bitmap2x, mask,
|
| + 0.2);
|
| + } else if (!result.get() ||
|
| + result->width() == size_in_dip_.width()) {
|
| + // The 2x resource pack may have the 1x image if its grd file
|
| + // points to 1x image. Fallback to 1x by returning empty image
|
| + // in this case. This 1x image will be scaled when drawn.
|
| + return gfx::ImageSkiaRep();
|
| + }
|
| + // If the size of 2x image isn't exactly 2x of 1x version,
|
| + // create ImageSkia as usual. This will end up with
|
| + // corrupted visual representation as the size of image doesn't
|
| + // match the expected size.
|
| + }
|
| + return gfx::ImageSkiaRep(*result.get(), scale_factor);
|
| + }
|
| +
|
| + private:
|
| + const int resource_id_;
|
| + const gfx::Size size_in_dip_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageSource);
|
| +};
|
|
|
| // static
|
| std::string ResourceBundle::InitSharedInstanceWithLocale(
|
| @@ -311,30 +361,23 @@ gfx::Image& ResourceBundle::GetImageNamed(int resource_id) {
|
| if (image.IsEmpty()) {
|
| DCHECK(!delegate_ && !data_packs_.empty()) <<
|
| "Missing call to SetResourcesDataDLL?";
|
| - gfx::ImageSkia image_skia;
|
| - for (size_t i = 0; i < data_packs_.size(); ++i) {
|
| - scoped_ptr<SkBitmap> bitmap(LoadBitmap(*data_packs_[i], resource_id));
|
| - if (bitmap.get()) {
|
| - ui::ScaleFactor scale_factor;
|
| - if (gfx::Screen::IsDIPEnabled()) {
|
| - scale_factor = GetActualScaleFactor(image_skia, *bitmap,
|
| - data_packs_[i]->GetScaleFactor());
|
| - } else {
|
| - scale_factor = ui::SCALE_FACTOR_100P;
|
| - }
|
| - image_skia.AddRepresentation(gfx::ImageSkiaRep(*bitmap, scale_factor));
|
| - }
|
| - }
|
|
|
| - if (image_skia.isNull()) {
|
| + // TODO(oshima): Pick the scale factor from currently used scale factors.
|
| + scoped_ptr<SkBitmap> bitmap(LoadBitmap(resource_id, SCALE_FACTOR_100P));
|
| + if (!bitmap.get()) {
|
| 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();
|
| }
|
|
|
| - Create2xResourceIfMissing(image_skia, resource_id);
|
| -
|
| + gfx::Size size_in_dip(bitmap->width(), bitmap->height());
|
| + gfx::ImageSkia image_skia(
|
| + new ResourceBundleImageSource(resource_id, size_in_dip),
|
| + size_in_dip);
|
| + image_skia.AddRepresentation(gfx::ImageSkiaRep(*bitmap.get(),
|
| + SCALE_FACTOR_100P));
|
| + image_skia.SetReadOnly();
|
| image = gfx::Image(image_skia);
|
| }
|
|
|
| @@ -537,7 +580,7 @@ void ResourceBundle::LoadFontsIfNecessary() {
|
| }
|
|
|
| SkBitmap* ResourceBundle::LoadBitmap(const ResourceHandle& data_handle,
|
| - int resource_id) {
|
| + int resource_id) const {
|
| scoped_refptr<base::RefCountedMemory> memory(
|
| data_handle.GetStaticMemory(resource_id));
|
| if (!memory)
|
| @@ -557,6 +600,18 @@ SkBitmap* ResourceBundle::LoadBitmap(const ResourceHandle& data_handle,
|
| return NULL;
|
| }
|
|
|
| +SkBitmap* ResourceBundle::LoadBitmap(int resource_id,
|
| + ScaleFactor scale_factor) const {
|
| + for (size_t i = 0; i < data_packs_.size(); ++i) {
|
| + if (data_packs_[i]->GetScaleFactor() == scale_factor) {
|
| + SkBitmap* bitmap = LoadBitmap(*data_packs_[i], resource_id);
|
| + if (bitmap)
|
| + return bitmap;
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| gfx::Image& ResourceBundle::GetEmptyImage() {
|
| base::AutoLock lock(*images_and_fonts_lock_);
|
|
|
|
|