diff options
author | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-22 19:31:26 +0000 |
---|---|---|
committer | sail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-22 19:31:26 +0000 |
commit | 17437dba596f54bbafe2814a2c70552e7396aa4a (patch) | |
tree | 90dd8b904c57df38d093d527eb80f0427d581a8a /ui | |
parent | 95d99c5d933de6eabd30aa22f5d20c7de43cb11e (diff) | |
download | chromium_src-17437dba596f54bbafe2814a2c70552e7396aa4a.zip chromium_src-17437dba596f54bbafe2814a2c70552e7396aa4a.tar.gz chromium_src-17437dba596f54bbafe2814a2c70552e7396aa4a.tar.bz2 |
Use large icon resource pak
This is a part of r82185 that was reverted. The change was reverted because it caused a performance regression.
In r82538 and r82584 I re-checked in code to split high-res icons into a seperate resource pak and load it.
This change adds code to actually use use the high-res icons.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/6897013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82688 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/base/resource/resource_bundle.cc | 7 | ||||
-rw-r--r-- | ui/gfx/image.cc | 45 | ||||
-rw-r--r-- | ui/gfx/image.h | 20 | ||||
-rw-r--r-- | ui/gfx/image_mac.mm | 12 | ||||
-rw-r--r-- | ui/gfx/image_mac_unittest.mm | 110 | ||||
-rw-r--r-- | ui/gfx/image_unittest.cc | 47 | ||||
-rw-r--r-- | ui/gfx/image_unittest_util.cc (renamed from ui/gfx/image_unittest.h) | 20 | ||||
-rw-r--r-- | ui/gfx/image_unittest_util.h | 33 | ||||
-rw-r--r-- | ui/ui_unittests.gypi | 4 |
9 files changed, 261 insertions, 37 deletions
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc index a8d9607..306a61e 100644 --- a/ui/base/resource/resource_bundle.cc +++ b/ui/base/resource/resource_bundle.cc @@ -131,8 +131,11 @@ gfx::Image& ResourceBundle::GetImageNamed(int resource_id) { if (images_.count(resource_id)) return *images_[resource_id]; - // TODO(sail): Add the large bitmap to the image as well. - gfx::Image* image = new gfx::Image(bitmap.release()); + std::vector<const SkBitmap*> bitmaps; + bitmaps.push_back(bitmap.release()); + if (large_bitmap.get()) + bitmaps.push_back(large_bitmap.release()); + gfx::Image* image = new gfx::Image(bitmaps); images_[resource_id] = image; return *image; } diff --git a/ui/gfx/image.cc b/ui/gfx/image.cc index 9395279..23edd96 100644 --- a/ui/gfx/image.cc +++ b/ui/gfx/image.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/logging.h" +#include "base/stl_util-inl.h" #include "third_party/skia/include/core/SkBitmap.h" #if defined(OS_LINUX) @@ -26,7 +27,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. -const SkBitmap* NSImageToSkBitmap(NSImage* image); +bool NSImageToSkBitmaps(NSImage* image, std::vector<const SkBitmap*>* bitmaps); #endif #if defined(OS_LINUX) @@ -84,20 +85,27 @@ class ImageRep { class SkBitmapRep : public ImageRep { public: explicit SkBitmapRep(const SkBitmap* bitmap) - : ImageRep(Image::kSkBitmapRep), - bitmap_(bitmap) { + : ImageRep(Image::kSkBitmapRep) { CHECK(bitmap); + bitmaps_.push_back(bitmap); + } + + explicit SkBitmapRep(const std::vector<const SkBitmap*>& bitmaps) + : ImageRep(Image::kSkBitmapRep), + bitmaps_(bitmaps) { + CHECK(!bitmaps_.empty()); } virtual ~SkBitmapRep() { - delete bitmap_; - bitmap_ = NULL; + STLDeleteElements(&bitmaps_); } - const SkBitmap* bitmap() const { return bitmap_; } + const SkBitmap* bitmap() const { return bitmaps_[0]; } + + const std::vector<const SkBitmap*>& bitmaps() const { return bitmaps_; } private: - const SkBitmap* bitmap_; + std::vector<const SkBitmap*> bitmaps_; DISALLOW_COPY_AND_ASSIGN(SkBitmapRep); }; @@ -193,6 +201,12 @@ Image::Image(const SkBitmap* bitmap) AddRepresentation(rep); } +Image::Image(const std::vector<const SkBitmap*>& bitmaps) + : storage_(new internal::ImageStorage(Image::kSkBitmapRep)) { + internal::SkBitmapRep* rep = new internal::SkBitmapRep(bitmaps); + AddRepresentation(rep); +} + #if defined(OS_LINUX) Image::Image(GdkPixbuf* pixbuf) : storage_(new internal::ImageStorage(Image::kGdkPixbufRep)) { @@ -289,8 +303,9 @@ internal::ImageRep* Image::GetRepresentation(RepresentationType rep_type) { #elif defined(OS_MACOSX) if (storage_->default_representation_type() == Image::kNSImageRep) { internal::NSImageRep* nsimage_rep = default_rep->AsNSImageRep(); - rep = new internal::SkBitmapRep( - internal::NSImageToSkBitmap(nsimage_rep->image())); + std::vector<const SkBitmap*> bitmaps; + CHECK(internal::NSImageToSkBitmaps(nsimage_rep->image(), &bitmaps)); + rep = new internal::SkBitmapRep(bitmaps); } #endif CHECK(rep); @@ -309,7 +324,7 @@ internal::ImageRep* Image::GetRepresentation(RepresentationType rep_type) { } #elif defined(OS_MACOSX) if (rep_type == Image::kNSImageRep) { - NSImage* image = gfx::SkBitmapToNSImage(*(skia_rep->bitmap())); + NSImage* image = gfx::SkBitmapsToNSImage(skia_rep->bitmaps()); base::mac::NSObjectRetain(image); native_rep = new internal::NSImageRep(image); } @@ -327,4 +342,14 @@ void Image::AddRepresentation(internal::ImageRep* rep) { storage_->representations().insert(std::make_pair(rep->type(), rep)); } +size_t Image::GetNumberOfSkBitmaps() { + return GetRepresentation(Image::kSkBitmapRep)->AsSkBitmapRep()-> + bitmaps().size(); +} + +const SkBitmap* Image::GetSkBitmapAtIndex(size_t index) { + return GetRepresentation(Image::kSkBitmapRep)->AsSkBitmapRep()-> + bitmaps()[index]; +} + } // namespace gfx diff --git a/ui/gfx/image.h b/ui/gfx/image.h index 518d8ac4..ed9508f 100644 --- a/ui/gfx/image.h +++ b/ui/gfx/image.h @@ -18,6 +18,7 @@ #pragma once #include <map> +#include <vector> #include "base/basictypes.h" #include "base/gtest_prod_util.h" @@ -29,6 +30,7 @@ class SkBitmap; namespace { class ImageTest; +class ImageMacTest; } namespace gfx { @@ -51,11 +53,18 @@ class Image { // Creates a new image with the default representation. The object will take // ownership of the image. 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(OS_LINUX) // Does not increase |pixbuf|'s reference count; expects to take ownership. explicit Image(GdkPixbuf* pixbuf); #elif defined(OS_MACOSX) // Does not retain |image|; expects to take ownership. + // A single NSImage object can contain multiple bitmaps so there's no reason + // to pass a vector of these. explicit Image(NSImage* image); #endif @@ -78,6 +87,16 @@ class Image { operator NSImage*(); #endif + // Gets the number of bitmaps in this image. This may cause a conversion + // to a bitmap representation. Note, this function and GetSkBitmapAtIndex() + // are primarily meant to be used by the theme provider. + size_t GetNumberOfSkBitmaps(); + + // Gets the bitmap at the given index. This may cause a conversion + // to a bitmap representation. Note, the internal ordering of bitmaps is not + // guaranteed. + const SkBitmap* GetSkBitmapAtIndex(size_t index); + // Inspects the representations map to see if the given type exists. bool HasRepresentation(RepresentationType type); @@ -103,6 +122,7 @@ class Image { scoped_refptr<internal::ImageStorage> storage_; friend class ::ImageTest; + friend class ::ImageMacTest; }; } // namespace gfx diff --git a/ui/gfx/image_mac.mm b/ui/gfx/image_mac.mm index b3dc977..55b4aa4 100644 --- a/ui/gfx/image_mac.mm +++ b/ui/gfx/image_mac.mm @@ -4,14 +4,22 @@ #import <AppKit/AppKit.h> +#include "base/memory/scoped_ptr.h" #include "skia/ext/skia_utils_mac.h" #include "third_party/skia/include/core/SkBitmap.h" namespace gfx { namespace internal { -const SkBitmap* NSImageToSkBitmap(NSImage* image) { - return new SkBitmap(::gfx::NSImageToSkBitmap(image, [image size], false)); +bool NSImageToSkBitmaps(NSImage* image, std::vector<const SkBitmap*>* bitmaps) { + for (NSImageRep* imageRep in [image representations]) { + scoped_ptr<SkBitmap> bitmap(new SkBitmap( + gfx::NSImageRepToSkBitmap(imageRep, [imageRep size], false))); + if (bitmap->isNull()) + return false; + bitmaps->push_back(bitmap.release()); + } + return true; } } // namespace internal diff --git a/ui/gfx/image_mac_unittest.mm b/ui/gfx/image_mac_unittest.mm new file mode 100644 index 0000000..1c333db --- /dev/null +++ b/ui/gfx/image_mac_unittest.mm @@ -0,0 +1,110 @@ +// 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. + +#include <Cocoa/Cocoa.h> + +#include "base/logging.h" +#include "base/memory/scoped_nsobject.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/image.h" +#include "ui/gfx/image_unittest_util.h" + +namespace { + +class ImageMacTest : public testing::Test { + public: + void CreateBitmapImageRep(int width, int height, NSImageRep** image_rep) { + scoped_nsobject<NSImage> image([[NSImage alloc] + initWithSize:NSMakeSize(width, height)]); + [image lockFocus]; + [[NSColor redColor] set]; + NSRectFill(NSMakeRect(0, 0, width, height)); + [image unlockFocus]; + EXPECT_TRUE([[[image representations] lastObject] + isKindOfClass:[NSImageRep class]]); + *image_rep = [[image representations] lastObject]; + } +}; + +namespace gt = gfx::test; + +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(width1, height1, &image_rep_1); + NSImageRep* image_rep_2; + CreateBitmapImageRep(width2, height2, &image_rep_2); + scoped_nsobject<NSImage> ns_image([[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()); + EXPECT_EQ(2u, image.GetNumberOfSkBitmaps()); + + const SkBitmap* bitmap1 = image.GetSkBitmapAtIndex(0); + EXPECT_TRUE(bitmap1); + const SkBitmap* bitmap2 = image.GetSkBitmapAtIndex(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); + } + + // GetNumberOfSkBitmaps and GetSkBitmapAtIndex should create a second + // representation. + EXPECT_EQ(2u, image.RepresentationCount()); +} + +TEST_F(ImageMacTest, MultiResolutionSkBitmapToNSImage) { + 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()); + EXPECT_EQ(2u, image.GetNumberOfSkBitmaps()); + + NSImage* ns_image = image; + EXPECT_TRUE(ns_image); + + 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 == 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, 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. + EXPECT_EQ(2u, image.RepresentationCount()); +} + +} // namespace diff --git a/ui/gfx/image_unittest.cc b/ui/gfx/image_unittest.cc index ce2a1f8..aba1ed6 100644 --- a/ui/gfx/image_unittest.cc +++ b/ui/gfx/image_unittest.cc @@ -6,7 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/image.h" -#include "ui/gfx/image_unittest.h" +#include "ui/gfx/image_unittest_util.h" #if defined(OS_LINUX) #include <gtk/gtk.h> @@ -30,7 +30,7 @@ class ImageTest : public testing::Test { namespace gt = gfx::test; TEST_F(ImageTest, SkiaToSkia) { - gfx::Image image(gt::CreateBitmap()); + gfx::Image image(gt::CreateBitmap(25, 25)); const SkBitmap* bitmap = static_cast<const SkBitmap*>(image); EXPECT_TRUE(bitmap); EXPECT_FALSE(bitmap->isNull()); @@ -48,7 +48,7 @@ TEST_F(ImageTest, SkiaToSkia) { } TEST_F(ImageTest, SkiaToSkiaRef) { - gfx::Image image(gt::CreateBitmap()); + gfx::Image image(gt::CreateBitmap(25, 25)); const SkBitmap& bitmap = static_cast<const SkBitmap&>(image); EXPECT_FALSE(bitmap.isNull()); @@ -64,7 +64,7 @@ TEST_F(ImageTest, SkiaToSkiaRef) { } TEST_F(ImageTest, SkiaToPlatform) { - gfx::Image image(gt::CreateBitmap()); + gfx::Image image(gt::CreateBitmap(25, 25)); const size_t kRepCount = kUsesSkiaNatively ? 1U : 2U; EXPECT_TRUE(image.HasRepresentation(gfx::Image::kSkBitmapRep)); @@ -127,7 +127,7 @@ TEST_F(ImageTest, CheckSkiaColor) { TEST_F(ImageTest, SwapRepresentations) { const size_t kRepCount = kUsesSkiaNatively ? 1U : 2U; - gfx::Image image1(gt::CreateBitmap()); + gfx::Image image1(gt::CreateBitmap(25, 25)); const SkBitmap* bitmap1 = image1; EXPECT_EQ(1U, image1.RepresentationCount()); @@ -148,7 +148,7 @@ TEST_F(ImageTest, SwapRepresentations) { TEST_F(ImageTest, Copy) { const size_t kRepCount = kUsesSkiaNatively ? 1U : 2U; - gfx::Image image1(gt::CreateBitmap()); + gfx::Image image1(gt::CreateBitmap(25, 25)); gfx::Image image2(image1); EXPECT_EQ(1U, image1.RepresentationCount()); @@ -171,6 +171,41 @@ TEST_F(ImageTest, Assign) { static_cast<const SkBitmap*>(image2)); } +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()); + EXPECT_EQ(2u, image.GetNumberOfSkBitmaps()); + + const SkBitmap* bitmap1 = image.GetSkBitmapAtIndex(0); + EXPECT_TRUE(bitmap1); + const SkBitmap* bitmap2 = image.GetSkBitmapAtIndex(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.GetNumberOfSkBitmaps()); +} + // Integration tests with UI toolkit frameworks require linking against the // Views library and cannot be here (gfx_unittests doesn't include it). They // instead live in /chrome/browser/ui/tests/ui_gfx_image_unittest.cc. diff --git a/ui/gfx/image_unittest.h b/ui/gfx/image_unittest_util.cc index 09abfce..b996a86 100644 --- a/ui/gfx/image_unittest.h +++ b/ui/gfx/image_unittest_util.cc @@ -5,10 +5,8 @@ // Because the unit tests for gfx::Image are spread across multiple // implementation files, this header contains the reusable components. -#ifndef UI_GFX_IMAGE_UNITTEST_H_ -#define UI_GFX_IMAGE_UNITTEST_H_ - #include "base/memory/scoped_ptr.h" +#include "ui/gfx/image_unittest_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -22,24 +20,16 @@ namespace gfx { namespace test { -#if defined(OS_MACOSX) -typedef NSImage* PlatformImage; -#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) -typedef GdkPixbuf* PlatformImage; -#else -typedef const SkBitmap* PlatformImage; -#endif - -SkBitmap* CreateBitmap() { +SkBitmap* CreateBitmap(int width, int height) { SkBitmap* bitmap = new SkBitmap(); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, 25, 25); + bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); bitmap->allocPixels(); bitmap->eraseRGB(255, 0, 0); return bitmap; } PlatformImage CreatePlatformImage() { - scoped_ptr<SkBitmap> bitmap(CreateBitmap()); + scoped_ptr<SkBitmap> bitmap(CreateBitmap(25, 25)); #if defined(OS_MACOSX) NSImage* image = gfx::SkBitmapToNSImage(*(bitmap.get())); base::mac::NSObjectRetain(image); @@ -63,5 +53,3 @@ gfx::Image::RepresentationType GetPlatformRepresentationType() { } // namespace test } // namespace gfx - -#endif // UI_GFX_IMAGE_UNITTEST_H_ diff --git a/ui/gfx/image_unittest_util.h b/ui/gfx/image_unittest_util.h new file mode 100644 index 0000000..f087f90 --- /dev/null +++ b/ui/gfx/image_unittest_util.h @@ -0,0 +1,33 @@ +// 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. + +// Because the unit tests for gfx::Image are spread across multiple +// implementation files, this header contains the reusable components. + +#ifndef UI_GFX_IMAGE_UNITTEST_UTIL_H_ +#define UI_GFX_IMAGE_UNITTEST_UTIL_H_ + +#include "ui/gfx/image.h" + +namespace gfx { +namespace test { + +#if defined(OS_MACOSX) +typedef NSImage* PlatformImage; +#elif defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) +typedef GdkPixbuf* PlatformImage; +#else +typedef const SkBitmap* PlatformImage; +#endif + +SkBitmap* CreateBitmap(int width, int height); + +PlatformImage CreatePlatformImage(); + +gfx::Image::RepresentationType GetPlatformRepresentationType(); + +} // namespace test +} // namespace gfx + +#endif // UI_GFX_IMAGE_UNITTEST_UTIL_H_ diff --git a/ui/ui_unittests.gypi b/ui/ui_unittests.gypi index 2a767a4..2867afb 100644 --- a/ui/ui_unittests.gypi +++ b/ui/ui_unittests.gypi @@ -32,8 +32,10 @@ 'gfx/codec/png_codec_unittest.cc', 'gfx/color_utils_unittest.cc', 'gfx/font_unittest.cc', + 'gfx/image_mac_unittest.mm', 'gfx/image_unittest.cc', - 'gfx/image_unittest.h', + 'gfx/image_unittest_util.h', + 'gfx/image_unittest_util.cc', 'gfx/insets_unittest.cc', 'gfx/rect_unittest.cc', 'gfx/run_all_unittests.cc', |