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

Side by Side Diff: ui/base/resource/resource_bundle.cc

Issue 6849030: Add support for multi resolution icons (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/resource/resource_bundle.h" 5 #include "ui/base/resource/resource_bundle.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "base/string_piece.h" 9 #include "base/string_piece.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "third_party/skia/include/core/SkBitmap.h" 12 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "ui/base/resource/data_pack.h" 13 #include "ui/base/resource/data_pack.h"
14 #include "ui/gfx/codec/png_codec.h" 14 #include "ui/gfx/codec/png_codec.h"
15 #include "ui/gfx/codec/tiff_codec.h"
15 #include "ui/gfx/font.h" 16 #include "ui/gfx/font.h"
16 #include "ui/gfx/image.h" 17 #include "ui/gfx/image.h"
17 18
18 namespace ui { 19 namespace ui {
19 20
20 namespace { 21 namespace {
21 22
22 // Font sizes relative to base font. 23 // Font sizes relative to base font.
23 #if defined(OS_CHROMEOS) && defined(CROS_FONTS_USING_BCI) 24 #if defined(OS_CHROMEOS) && defined(CROS_FONTS_USING_BCI)
24 const int kSmallFontSizeDelta = -3; 25 const int kSmallFontSizeDelta = -3;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 CHECK(g_shared_instance_ != NULL); 102 CHECK(g_shared_instance_ != NULL);
102 return *g_shared_instance_; 103 return *g_shared_instance_;
103 } 104 }
104 105
105 SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) { 106 SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) {
106 const SkBitmap* bitmap = 107 const SkBitmap* bitmap =
107 static_cast<const SkBitmap*>(GetImageNamed(resource_id)); 108 static_cast<const SkBitmap*>(GetImageNamed(resource_id));
108 return const_cast<SkBitmap*>(bitmap); 109 return const_cast<SkBitmap*>(bitmap);
109 } 110 }
110 111
112 bool ResourceBundle::GetBitmapsNamed(int resource_id,
113 std::vector<SkBitmap*>& bitmaps) {
114 std::vector<gfx::Image*> images;
115 if (!GetImagesNamed(resource_id, images))
116 return false;
117
118 for (std::vector<gfx::Image*>::iterator it = images.begin();
119 it != images.end(); ++it) {
120 const SkBitmap* bitmap = static_cast<const SkBitmap*>(**it);
121 bitmaps.push_back(const_cast<SkBitmap*>(bitmap));
122 }
123 return true;
124 }
125
111 gfx::Image& ResourceBundle::GetImageNamed(int resource_id) { 126 gfx::Image& ResourceBundle::GetImageNamed(int resource_id) {
112 // Check to see if the image is already in the cache. 127 std::vector<gfx::Image*> images;
113 { 128 if (GetImagesNamed(resource_id, images)) {
114 base::AutoLock lock_scope(*lock_); 129 if (!images.empty())
115 ImageMap::const_iterator found = images_.find(resource_id); 130 return **images.begin();
116 if (found != images_.end())
117 return *found->second;
118 }
119
120 scoped_ptr<SkBitmap> bitmap(LoadBitmap(resources_data_, resource_id));
121 if (bitmap.get()) {
122 // The load was successful, so cache the image.
123 base::AutoLock lock_scope(*lock_);
124
125 // Another thread raced the load and has already cached the image.
126 if (images_.count(resource_id))
127 return *images_[resource_id];
128
129 gfx::Image* image = new gfx::Image(bitmap.release());
130 images_[resource_id] = image;
131 return *image;
132 } 131 }
133 132
134 // The load failed to retrieve the image; show a debugging red square. 133 // The load failed to retrieve the image; show a debugging red square.
135 LOG(WARNING) << "Unable to load image with id " << resource_id; 134 NOTREACHED();
136 NOTREACHED(); // Want to assert in debug mode.
137 return *GetEmptyImage(); 135 return *GetEmptyImage();
138 } 136 }
139 137
138 bool ResourceBundle::GetImagesNamed(int resource_id,
139 std::vector<gfx::Image*>& images) {
140 // Check to see if the image is already in the cache.
141 if (GetImagesFromCacheNamed(resource_id, images)) {
142 return true;
143 }
144
145 std::vector<SkBitmap> bitmaps;
146 if (LoadBitmaps(resources_data_, resource_id, bitmaps)) {
147 // The load was successful, so cache the images.
148 {
149 base::AutoLock lock_scope(*lock_);
150
151 // Has another thread raced the load and has already cached the image?
152 if (!images_.count(resource_id)) {
153 std::vector<gfx::Image*>* images_ptr = new std::vector<gfx::Image*>;
154 for (std::vector<SkBitmap>::iterator it = bitmaps.begin();
155 it != bitmaps.end(); ++it) {
156 SkBitmap* bitmap = new SkBitmap(*it);
157 gfx::Image* image = new gfx::Image(bitmap);
158 images_ptr->push_back(image);
159 images_[resource_id] = images_ptr;
160 }
161 }
162 }
163 return GetImagesFromCacheNamed(resource_id, images);
164 }
165
166 // The load failed to retrieve the image.
167 LOG(WARNING) << "Unable to load image with id " << resource_id;
168 NOTREACHED(); // Want to assert in debug mode.
169 return false;
170 }
171
172 bool ResourceBundle::GetImagesFromCacheNamed(int resource_id,
173 std::vector<gfx::Image*>& images) {
174 base::AutoLock lock_scope(*lock_);
175
176 ImageMap::const_iterator found = images_.find(resource_id);
177 if (found == images_.end())
178 return false;
179
180 std::vector<gfx::Image*>* found_images = found->second;
181 for (std::vector<gfx::Image*>::const_iterator it = found_images->begin();
182 it != found_images->end(); ++it) {
183 images.push_back(*it);
184 }
185 return true;
186 }
187
140 #if !defined(OS_MACOSX) && !defined(OS_LINUX) 188 #if !defined(OS_MACOSX) && !defined(OS_LINUX)
141 // Only Mac and Linux have non-Skia native image types. All other platforms use 189 // Only Mac and Linux have non-Skia native image types. All other platforms use
142 // Skia natively, so just use GetImageNamed(). 190 // Skia natively, so just use GetImageNamed().
143 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { 191 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) {
144 return GetImageNamed(resource_id); 192 return GetImageNamed(resource_id);
145 } 193 }
146 #endif 194 #endif
147 195
148 RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytes( 196 RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytes(
149 int resource_id) const { 197 int resource_id) const {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 LoadFontsIfNecessary(); 235 LoadFontsIfNecessary();
188 } 236 }
189 237
190 ResourceBundle::ResourceBundle() 238 ResourceBundle::ResourceBundle()
191 : lock_(new base::Lock), 239 : lock_(new base::Lock),
192 resources_data_(NULL), 240 resources_data_(NULL),
193 locale_resources_data_(NULL) { 241 locale_resources_data_(NULL) {
194 } 242 }
195 243
196 void ResourceBundle::FreeImages() { 244 void ResourceBundle::FreeImages() {
197 STLDeleteContainerPairSecondPointers(images_.begin(), 245 for (ImageMap::iterator i = images_.begin(); i != images_.end(); ++i) {
198 images_.end()); 246 STLDeleteContainerPointers(i->second->begin(), i->second->end());
199 images_.clear(); 247 }
248 STLDeleteValues(&images_);
200 } 249 }
201 250
202 void ResourceBundle::LoadFontsIfNecessary() { 251 void ResourceBundle::LoadFontsIfNecessary() {
203 lock_->AssertAcquired(); 252 lock_->AssertAcquired();
204 if (!base_font_.get()) { 253 if (!base_font_.get()) {
205 base_font_.reset(new gfx::Font()); 254 base_font_.reset(new gfx::Font());
206 255
207 bold_font_.reset(new gfx::Font()); 256 bold_font_.reset(new gfx::Font());
208 *bold_font_ = 257 *bold_font_ =
209 base_font_->DeriveFont(0, base_font_->GetStyle() | gfx::Font::BOLD); 258 base_font_->DeriveFont(0, base_font_->GetStyle() | gfx::Font::BOLD);
210 259
211 small_font_.reset(new gfx::Font()); 260 small_font_.reset(new gfx::Font());
212 *small_font_ = base_font_->DeriveFont(kSmallFontSizeDelta); 261 *small_font_ = base_font_->DeriveFont(kSmallFontSizeDelta);
213 262
214 medium_font_.reset(new gfx::Font()); 263 medium_font_.reset(new gfx::Font());
215 *medium_font_ = base_font_->DeriveFont(kMediumFontSizeDelta); 264 *medium_font_ = base_font_->DeriveFont(kMediumFontSizeDelta);
216 265
217 medium_bold_font_.reset(new gfx::Font()); 266 medium_bold_font_.reset(new gfx::Font());
218 *medium_bold_font_ = 267 *medium_bold_font_ =
219 base_font_->DeriveFont(kMediumFontSizeDelta, 268 base_font_->DeriveFont(kMediumFontSizeDelta,
220 base_font_->GetStyle() | gfx::Font::BOLD); 269 base_font_->GetStyle() | gfx::Font::BOLD);
221 270
222 large_font_.reset(new gfx::Font()); 271 large_font_.reset(new gfx::Font());
223 *large_font_ = base_font_->DeriveFont(kLargeFontSizeDelta); 272 *large_font_ = base_font_->DeriveFont(kLargeFontSizeDelta);
224 } 273 }
225 } 274 }
226 275
227 /* static */ 276 /* static */
228 SkBitmap* ResourceBundle::LoadBitmap(DataHandle data_handle, int resource_id) { 277 bool ResourceBundle::LoadBitmaps(DataHandle data_handle, int resource_id,
278 std::vector<SkBitmap>& bitmaps) {
229 scoped_refptr<RefCountedMemory> memory( 279 scoped_refptr<RefCountedMemory> memory(
230 LoadResourceBytes(data_handle, resource_id)); 280 LoadResourceBytes(data_handle, resource_id));
231 if (!memory) 281 if (!memory)
232 return NULL; 282 return false;
233 283
234 SkBitmap bitmap; 284 SkBitmap bitmap;
235 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), &bitmap)) { 285 if (gfx::PNGCodec::Decode(memory->front(), memory->size(), &bitmap)) {
236 NOTREACHED() << "Unable to decode theme image resource " << resource_id; 286 bitmaps.push_back(bitmap);
237 return NULL; 287 return true;
238 } 288 }
239 289
240 return new SkBitmap(bitmap); 290 if (gfx::TIFFCodec::Decode(memory->front(), memory->size(), bitmaps)) {
291 return true;
292 }
293
294 NOTREACHED() << "Unable to decode theme image resource " << resource_id;
295 return false;
241 } 296 }
242 297
243 gfx::Image* ResourceBundle::GetEmptyImage() { 298 gfx::Image* ResourceBundle::GetEmptyImage() {
244 base::AutoLock lock(*lock_); 299 base::AutoLock lock(*lock_);
245 300
246 static gfx::Image* empty_image = NULL; 301 static gfx::Image* empty_image = NULL;
247 if (!empty_image) { 302 if (!empty_image) {
248 // The placeholder bitmap is bright red so people notice the problem. 303 // The placeholder bitmap is bright red so people notice the problem.
249 // This bitmap will be leaked, but this code should never be hit. 304 // This bitmap will be leaked, but this code should never be hit.
250 SkBitmap* bitmap = new SkBitmap(); 305 SkBitmap* bitmap = new SkBitmap();
(...skipping 29 matching lines...) Expand all
280 int resource_id, base::StringPiece* data) const { 335 int resource_id, base::StringPiece* data) const {
281 return data_pack_->GetStringPiece(static_cast<uint32>(resource_id), data); 336 return data_pack_->GetStringPiece(static_cast<uint32>(resource_id), data);
282 } 337 }
283 338
284 RefCountedStaticMemory* ResourceBundle::LoadedDataPack::GetStaticMemory( 339 RefCountedStaticMemory* ResourceBundle::LoadedDataPack::GetStaticMemory(
285 int resource_id) const { 340 int resource_id) const {
286 return data_pack_->GetStaticMemory(resource_id); 341 return data_pack_->GetStaticMemory(resource_id);
287 } 342 }
288 343
289 } // namespace ui 344 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698