Chromium Code Reviews| 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..1c9e69a046e75cccca740b9ff775c48d6d5fad77 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,81 @@ 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; |
| +class ResourceBundle::ResourceBundleImageSource : public gfx::ImageSkiaSource { |
|
sky
2012/08/23 19:44:09
Add a description.
oshima
2012/08/24 16:45:34
Done.
|
| + 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: |
| + int resource_id_; |
|
sky
2012/08/23 19:44:09
Make these two const.
oshima
2012/08/24 16:45:34
Done.
|
| + gfx::Size size_in_dip_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageSource); |
| +}; |
| // static |
| std::string ResourceBundle::InitSharedInstanceWithLocale( |
| @@ -311,30 +354,22 @@ 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 = gfx::Image(image_skia); |
| } |
| @@ -537,7 +572,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 +592,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_); |