Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(473)

Unified Diff: ui/base/resource/resource_bundle.cc

Issue 10820049: Load 2x resources on demand (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updated comment Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/base/resource/resource_bundle.h ('k') | ui/gfx/image/image_skia.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_);
« no previous file with comments | « ui/base/resource/resource_bundle.h ('k') | ui/gfx/image/image_skia.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698