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

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

Issue 10270023: Add new ResourceBundle::Delegate interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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
« no previous file with comments | « ui/base/resource/resource_bundle.h ('k') | ui/base/resource/resource_bundle_android.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ref_counted_memory.h" 12 #include "base/memory/ref_counted_memory.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/path_service.h" 14 #include "base/path_service.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/string_piece.h" 16 #include "base/string_piece.h"
17 #include "base/synchronization/lock.h" 17 #include "base/synchronization/lock.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "third_party/skia/include/core/SkBitmap.h" 20 #include "third_party/skia/include/core/SkBitmap.h"
21 #include "ui/base/l10n/l10n_util.h" 21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/data_pack.h" 22 #include "ui/base/resource/data_pack.h"
23 #include "ui/base/ui_base_paths.h" 23 #include "ui/base/ui_base_paths.h"
24 #include "ui/base/ui_base_switches.h" 24 #include "ui/base/ui_base_switches.h"
25 #include "ui/gfx/codec/jpeg_codec.h" 25 #include "ui/gfx/codec/jpeg_codec.h"
26 #include "ui/gfx/codec/png_codec.h" 26 #include "ui/gfx/codec/png_codec.h"
27 #include "ui/gfx/font.h"
28 #include "ui/gfx/image/image.h"
29 27
30 namespace ui { 28 namespace ui {
31 29
32 namespace { 30 namespace {
33 31
34 // Font sizes relative to base font. 32 // Font sizes relative to base font.
35 #if defined(OS_CHROMEOS) && defined(CROS_FONTS_USING_BCI) 33 #if defined(OS_CHROMEOS) && defined(CROS_FONTS_USING_BCI)
36 const int kSmallFontSizeDelta = -3; 34 const int kSmallFontSizeDelta = -3;
37 const int kMediumFontSizeDelta = 2; 35 const int kMediumFontSizeDelta = 2;
38 const int kLargeFontSizeDelta = 7; 36 const int kLargeFontSizeDelta = 7;
39 #else 37 #else
40 const int kSmallFontSizeDelta = -2; 38 const int kSmallFontSizeDelta = -2;
41 const int kMediumFontSizeDelta = 3; 39 const int kMediumFontSizeDelta = 3;
42 const int kLargeFontSizeDelta = 8; 40 const int kLargeFontSizeDelta = 8;
43 #endif 41 #endif
44 42
45 } // namespace 43 } // namespace
46 44
47 ResourceBundle* ResourceBundle::g_shared_instance_ = NULL; 45 ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;
48 46
49 // static 47 // static
50 std::string ResourceBundle::InitSharedInstanceWithLocale( 48 std::string ResourceBundle::InitSharedInstanceWithLocale(
51 const std::string& pref_locale) { 49 const std::string& pref_locale, Delegate* delegate) {
52 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; 50 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
53 g_shared_instance_ = new ResourceBundle(); 51 g_shared_instance_ = new ResourceBundle(delegate);
54 52
55 g_shared_instance_->LoadCommonResources(); 53 g_shared_instance_->LoadCommonResources();
56 return g_shared_instance_->LoadLocaleResources(pref_locale); 54 return g_shared_instance_->LoadLocaleResources(pref_locale);
57 } 55 }
58 56
59 // static 57 // static
60 void ResourceBundle::InitSharedInstanceWithPakFile(const FilePath& path) { 58 void ResourceBundle::InitSharedInstanceWithPakFile(const FilePath& path) {
61 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; 59 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
62 g_shared_instance_ = new ResourceBundle(); 60 g_shared_instance_ = new ResourceBundle(NULL);
63 61
64 g_shared_instance_->LoadTestResources(path); 62 g_shared_instance_->LoadTestResources(path);
65 } 63 }
66 64
67 // static 65 // static
68 void ResourceBundle::CleanupSharedInstance() { 66 void ResourceBundle::CleanupSharedInstance() {
69 if (g_shared_instance_) { 67 if (g_shared_instance_) {
70 delete g_shared_instance_; 68 delete g_shared_instance_;
71 g_shared_instance_ = NULL; 69 g_shared_instance_ = NULL;
72 } 70 }
73 } 71 }
74 72
75 // static 73 // static
76 bool ResourceBundle::HasSharedInstance() { 74 bool ResourceBundle::HasSharedInstance() {
77 return g_shared_instance_ != NULL; 75 return g_shared_instance_ != NULL;
78 } 76 }
79 77
80 // static 78 // static
81 ResourceBundle& ResourceBundle::GetSharedInstance() { 79 ResourceBundle& ResourceBundle::GetSharedInstance() {
82 // Must call InitSharedInstance before this function. 80 // Must call InitSharedInstance before this function.
83 CHECK(g_shared_instance_ != NULL); 81 CHECK(g_shared_instance_ != NULL);
84 return *g_shared_instance_; 82 return *g_shared_instance_;
85 } 83 }
86 84
87 // static
88 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { 85 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) {
89 return !GetLocaleFilePath(locale).empty(); 86 return !GetLocaleFilePath(locale).empty();
90 } 87 }
91 88
92 void ResourceBundle::AddDataPack(const FilePath& path, float scale_factor) { 89 void ResourceBundle::AddDataPack(const FilePath& path, float scale_factor) {
90 // Do not pass an empty |path| value to this method. If the absolute path is
91 // unknown pass just the pack file name.
92 DCHECK(!path.empty());
93
94 FilePath pack_path = path;
95 if (delegate_)
96 pack_path = delegate_->GetPathForResourcePack(pack_path, scale_factor);
97
98 // Don't try to load empty values or values that are not absolute paths.
99 if (pack_path.empty() || !pack_path.IsAbsolute())
100 return;
101
93 scoped_ptr<DataPack> data_pack( 102 scoped_ptr<DataPack> data_pack(
94 new DataPack(ResourceHandle::kScaleFactor100x)); 103 new DataPack(ResourceHandle::kScaleFactor100x));
95 if (data_pack->Load(path)) { 104 if (data_pack->Load(pack_path)) {
96 data_packs_.push_back(data_pack.release()); 105 data_packs_.push_back(data_pack.release());
97 } else { 106 } else {
98 LOG(ERROR) << "Failed to load " << path.value() 107 LOG(ERROR) << "Failed to load " << pack_path.value()
99 << "\nSome features may not be available."; 108 << "\nSome features may not be available.";
100 } 109 }
101 } 110 }
102 111
103 #if !defined(OS_MACOSX) 112 #if !defined(OS_MACOSX)
104 // static
105 FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale) { 113 FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale) {
114 if (app_locale.empty())
115 return FilePath();
116
106 FilePath locale_file_path; 117 FilePath locale_file_path;
118
107 #if defined(OS_ANDROID) 119 #if defined(OS_ANDROID)
108 PathService::Get(base::DIR_ANDROID_APP_DATA, &locale_file_path); 120 PathService::Get(base::DIR_ANDROID_APP_DATA, &locale_file_path);
109 locale_file_path = locale_file_path.Append(FILE_PATH_LITERAL("paks")); 121 locale_file_path = locale_file_path.Append(FILE_PATH_LITERAL("paks"));
110 #else 122 #else
111 PathService::Get(ui::DIR_LOCALES, &locale_file_path); 123 PathService::Get(ui::DIR_LOCALES, &locale_file_path);
112 #endif 124 #endif
113 if (locale_file_path.empty()) 125
114 return locale_file_path; 126 if (!locale_file_path.empty())
115 if (app_locale.empty()) 127 locale_file_path = locale_file_path.AppendASCII(app_locale + ".pak");
128
129 if (delegate_) {
130 locale_file_path =
131 delegate_->GetPathForLocalePack(locale_file_path, app_locale);
132 }
133
134 // Don't try to load empty values or values that are not absolute paths.
135 if (locale_file_path.empty() || !locale_file_path.IsAbsolute())
116 return FilePath(); 136 return FilePath();
117 locale_file_path = locale_file_path.AppendASCII(app_locale + ".pak"); 137
118 if (!file_util::PathExists(locale_file_path)) 138 if (!file_util::PathExists(locale_file_path))
119 return FilePath(); 139 return FilePath();
140
120 return locale_file_path; 141 return locale_file_path;
121 } 142 }
122 #endif 143 #endif
123 144
124 std::string ResourceBundle::LoadLocaleResources( 145 std::string ResourceBundle::LoadLocaleResources(
125 const std::string& pref_locale) { 146 const std::string& pref_locale) {
126 DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; 147 DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded";
127 std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); 148 std::string app_locale = l10n_util::GetApplicationLocale(pref_locale);
128 FilePath locale_file_path = GetOverriddenPakPath(); 149 FilePath locale_file_path = GetOverriddenPakPath();
129 if (locale_file_path.empty()) { 150 if (locale_file_path.empty()) {
130 CommandLine *command_line = CommandLine::ForCurrentProcess(); 151 CommandLine* command_line = CommandLine::ForCurrentProcess();
131 if (command_line->HasSwitch(switches::kLocalePak)) { 152 if (command_line->HasSwitch(switches::kLocalePak)) {
132 locale_file_path = 153 locale_file_path =
133 command_line->GetSwitchValuePath(switches::kLocalePak); 154 command_line->GetSwitchValuePath(switches::kLocalePak);
134 } else { 155 } else {
135 locale_file_path = GetLocaleFilePath(app_locale); 156 locale_file_path = GetLocaleFilePath(app_locale);
136 } 157 }
137 } 158 }
138 159
139 if (locale_file_path.empty()) { 160 if (locale_file_path.empty()) {
140 // It's possible that there is no locale.pak. 161 // It's possible that there is no locale.pak.
141 NOTREACHED();
142 return std::string(); 162 return std::string();
143 } 163 }
144 164
145 scoped_ptr<DataPack> data_pack( 165 scoped_ptr<DataPack> data_pack(
146 new DataPack(ResourceHandle::kScaleFactor100x)); 166 new DataPack(ResourceHandle::kScaleFactor100x));
147 if (!data_pack->Load(locale_file_path)) { 167 if (!data_pack->Load(locale_file_path)) {
148 UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError", 168 UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError",
149 logging::GetLastSystemErrorCode(), 16000); 169 logging::GetLastSystemErrorCode(), 16000);
150 NOTREACHED() << "failed to load locale.pak"; 170 NOTREACHED() << "failed to load locale.pak";
151 return std::string(); 171 return std::string();
(...skipping 12 matching lines...) Expand all
164 184
165 data_pack.reset(new DataPack(ResourceHandle::kScaleFactor100x)); 185 data_pack.reset(new DataPack(ResourceHandle::kScaleFactor100x));
166 if (data_pack->Load(path)) 186 if (data_pack->Load(path))
167 locale_resources_data_.reset(data_pack.release()); 187 locale_resources_data_.reset(data_pack.release());
168 } 188 }
169 189
170 void ResourceBundle::UnloadLocaleResources() { 190 void ResourceBundle::UnloadLocaleResources() {
171 locale_resources_data_.reset(); 191 locale_resources_data_.reset();
172 } 192 }
173 193
174 string16 ResourceBundle::GetLocalizedString(int message_id) {
175 // Ensure that ReloadLocaleResources() doesn't drop the resources while
176 // we're using them.
177 base::AutoLock lock_scope(*locale_resources_data_lock_);
178
179 // If for some reason we were unable to load the resources , return an empty
180 // string (better than crashing).
181 if (!locale_resources_data_.get()) {
182 LOG(WARNING) << "locale resources are not loaded";
183 return string16();
184 }
185
186 base::StringPiece data;
187 if (!locale_resources_data_->GetStringPiece(message_id, &data)) {
188 // Fall back on the main data pack (shouldn't be any strings here except in
189 // unittests).
190 data = GetRawDataResource(message_id);
191 if (data.empty()) {
192 NOTREACHED() << "unable to find resource: " << message_id;
193 return string16();
194 }
195 }
196
197 // Strings should not be loaded from a data pack that contains binary data.
198 ResourceHandle::TextEncodingType encoding =
199 locale_resources_data_->GetTextEncodingType();
200 DCHECK(encoding == ResourceHandle::UTF16 || encoding == ResourceHandle::UTF8)
201 << "requested localized string from binary pack file";
202
203 // Data pack encodes strings as either UTF8 or UTF16.
204 string16 msg;
205 if (encoding == ResourceHandle::UTF16) {
206 msg = string16(reinterpret_cast<const char16*>(data.data()),
207 data.length() / 2);
208 } else if (encoding == ResourceHandle::UTF8) {
209 msg = UTF8ToUTF16(data);
210 }
211 return msg;
212 }
213
214 void ResourceBundle::OverrideLocalePakForTest(const FilePath& pak_path) { 194 void ResourceBundle::OverrideLocalePakForTest(const FilePath& pak_path) {
215 overridden_pak_path_ = pak_path; 195 overridden_pak_path_ = pak_path;
216 } 196 }
217 197
218 const FilePath& ResourceBundle::GetOverriddenPakPath() { 198 const FilePath& ResourceBundle::GetOverriddenPakPath() {
219 return overridden_pak_path_; 199 return overridden_pak_path_;
220 } 200 }
221 201
222 std::string ResourceBundle::ReloadLocaleResources( 202 std::string ResourceBundle::ReloadLocaleResources(
223 const std::string& pref_locale) { 203 const std::string& pref_locale) {
224 base::AutoLock lock_scope(*locale_resources_data_lock_); 204 base::AutoLock lock_scope(*locale_resources_data_lock_);
225 UnloadLocaleResources(); 205 UnloadLocaleResources();
226 return LoadLocaleResources(pref_locale); 206 return LoadLocaleResources(pref_locale);
227 } 207 }
228 208
229 SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) { 209 SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) {
230 const SkBitmap* bitmap = GetImageNamed(resource_id).ToSkBitmap(); 210 const SkBitmap* bitmap = GetImageNamed(resource_id).ToSkBitmap();
231 return const_cast<SkBitmap*>(bitmap); 211 return const_cast<SkBitmap*>(bitmap);
232 } 212 }
233 213
234 gfx::Image& ResourceBundle::GetImageNamed(int resource_id) { 214 gfx::Image& ResourceBundle::GetImageNamed(int resource_id) {
235 // Check to see if the image is already in the cache. 215 // Check to see if the image is already in the cache.
236 { 216 {
237 base::AutoLock lock_scope(*images_and_fonts_lock_); 217 base::AutoLock lock_scope(*images_and_fonts_lock_);
238 ImageMap::const_iterator found = images_.find(resource_id); 218 if (images_.count(resource_id))
239 if (found != images_.end()) 219 return images_[resource_id];
240 return *found->second;
241 } 220 }
242 221
243 DCHECK(!data_packs_.empty()) << "Missing call to SetResourcesDataDLL?"; 222 gfx::Image image;
244 ScopedVector<const SkBitmap> bitmaps; 223 if (delegate_)
245 for (size_t i = 0; i < data_packs_.size(); ++i) { 224 image = delegate_->GetImageNamed(resource_id);
246 SkBitmap* bitmap = LoadBitmap(*data_packs_[i], resource_id);
247 if (bitmap)
248 bitmaps.push_back(bitmap);
249 }
250 225
251 if (bitmaps.empty()) { 226 if (image.IsEmpty()) {
252 LOG(WARNING) << "Unable to load image with id " << resource_id; 227 DCHECK(!delegate_ && !data_packs_.empty()) <<
253 NOTREACHED(); // Want to assert in debug mode. 228 "Missing call to SetResourcesDataDLL?";
254 // The load failed to retrieve the image; show a debugging red square. 229 ScopedVector<const SkBitmap> bitmaps;
255 return *GetEmptyImage(); 230 for (size_t i = 0; i < data_packs_.size(); ++i) {
231 SkBitmap* bitmap = LoadBitmap(*data_packs_[i], resource_id);
232 if (bitmap)
233 bitmaps.push_back(bitmap);
234 }
235
236 if (bitmaps.empty()) {
237 LOG(WARNING) << "Unable to load image with id " << resource_id;
238 NOTREACHED(); // Want to assert in debug mode.
239 // The load failed to retrieve the image; show a debugging red square.
240 return GetEmptyImage();
241 }
242
243 std::vector<const SkBitmap*> tmp_bitmaps;
244 bitmaps.release(&tmp_bitmaps);
245
246 // Takes ownership of bitmaps.
247 image = gfx::Image(tmp_bitmaps);
256 } 248 }
257 249
258 // The load was successful, so cache the image. 250 // The load was successful, so cache the image.
259 base::AutoLock lock_scope(*images_and_fonts_lock_); 251 base::AutoLock lock_scope(*images_and_fonts_lock_);
260 252
261 // Another thread raced the load and has already cached the image. 253 // Another thread raced the load and has already cached the image.
262 if (images_.count(resource_id)) 254 if (images_.count(resource_id))
263 return *images_[resource_id]; 255 return images_[resource_id];
264 256
265 std::vector<const SkBitmap*> tmp_bitmaps;
266 bitmaps.release(&tmp_bitmaps);
267 // Takes ownership of bitmaps.
268 gfx::Image* image = new gfx::Image(tmp_bitmaps);
269 images_[resource_id] = image; 257 images_[resource_id] = image;
270 return *image; 258 return images_[resource_id];
271 } 259 }
272 260
273 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { 261 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) {
274 return GetNativeImageNamed(resource_id, RTL_DISABLED); 262 return GetNativeImageNamed(resource_id, RTL_DISABLED);
275 } 263 }
276 264
277 base::RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytes( 265 base::RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytes(
278 int resource_id) const { 266 int resource_id) const {
279 for (size_t i = 0; i < data_packs_.size(); ++i) { 267 base::RefCountedStaticMemory* bytes = NULL;
280 base::RefCountedStaticMemory* bytes = 268 if (delegate_)
281 data_packs_[i]->GetStaticMemory(resource_id); 269 bytes = delegate_->LoadDataResourceBytes(resource_id);
282 if (bytes) 270
283 return bytes; 271 if (!bytes) {
272 for (size_t i = 0; i < data_packs_.size() && !bytes; ++i)
273 bytes = data_packs_[i]->GetStaticMemory(resource_id);
284 } 274 }
285 275
286 return NULL; 276 return bytes;
287 } 277 }
288 278
289 base::StringPiece ResourceBundle::GetRawDataResource(int resource_id) const { 279 base::StringPiece ResourceBundle::GetRawDataResource(int resource_id) const {
280 base::StringPiece data;
281 if (delegate_ && delegate_->GetRawDataResource(resource_id, &data))
282 return data;
283
290 DCHECK(locale_resources_data_.get()); 284 DCHECK(locale_resources_data_.get());
291 base::StringPiece data;
292 if (locale_resources_data_->GetStringPiece(resource_id, &data)) 285 if (locale_resources_data_->GetStringPiece(resource_id, &data))
293 return data; 286 return data;
294 287
295 for (size_t i = 0; i < data_packs_.size(); ++i) { 288 for (size_t i = 0; i < data_packs_.size(); ++i) {
296 if (data_packs_[i]->GetStringPiece(resource_id, &data)) 289 if (data_packs_[i]->GetStringPiece(resource_id, &data))
297 return data; 290 return data;
298 } 291 }
299 292
300 return base::StringPiece(); 293 return base::StringPiece();
301 } 294 }
302 295
296 string16 ResourceBundle::GetLocalizedString(int message_id) {
297 string16 string;
298 if (delegate_ && delegate_->GetLocalizedString(message_id, &string))
299 return string;
300
301 // Ensure that ReloadLocaleResources() doesn't drop the resources while
302 // we're using them.
303 base::AutoLock lock_scope(*locale_resources_data_lock_);
304
305 // If for some reason we were unable to load the resources , return an empty
306 // string (better than crashing).
307 if (!locale_resources_data_.get()) {
308 LOG(WARNING) << "locale resources are not loaded";
309 return string16();
310 }
311
312 base::StringPiece data;
313 if (!locale_resources_data_->GetStringPiece(message_id, &data)) {
314 // Fall back on the main data pack (shouldn't be any strings here except in
315 // unittests).
316 data = GetRawDataResource(message_id);
317 if (data.empty()) {
318 NOTREACHED() << "unable to find resource: " << message_id;
319 return string16();
320 }
321 }
322
323 // Strings should not be loaded from a data pack that contains binary data.
324 ResourceHandle::TextEncodingType encoding =
325 locale_resources_data_->GetTextEncodingType();
326 DCHECK(encoding == ResourceHandle::UTF16 || encoding == ResourceHandle::UTF8)
327 << "requested localized string from binary pack file";
328
329 // Data pack encodes strings as either UTF8 or UTF16.
330 string16 msg;
331 if (encoding == ResourceHandle::UTF16) {
332 msg = string16(reinterpret_cast<const char16*>(data.data()),
333 data.length() / 2);
334 } else if (encoding == ResourceHandle::UTF8) {
335 msg = UTF8ToUTF16(data);
336 }
337 return msg;
338 }
339
303 const gfx::Font& ResourceBundle::GetFont(FontStyle style) { 340 const gfx::Font& ResourceBundle::GetFont(FontStyle style) {
304 { 341 {
305 base::AutoLock lock_scope(*images_and_fonts_lock_); 342 base::AutoLock lock_scope(*images_and_fonts_lock_);
306 LoadFontsIfNecessary(); 343 LoadFontsIfNecessary();
307 } 344 }
308 switch (style) { 345 switch (style) {
309 case BoldFont: 346 case BoldFont:
310 return *bold_font_; 347 return *bold_font_;
311 case SmallFont: 348 case SmallFont:
312 return *small_font_; 349 return *small_font_;
313 case MediumFont: 350 case MediumFont:
314 return *medium_font_; 351 return *medium_font_;
315 case MediumBoldFont: 352 case MediumBoldFont:
316 return *medium_bold_font_; 353 return *medium_bold_font_;
317 case LargeFont: 354 case LargeFont:
318 return *large_font_; 355 return *large_font_;
319 case LargeBoldFont: 356 case LargeBoldFont:
320 return *large_bold_font_; 357 return *large_bold_font_;
321 default: 358 default:
322 return *base_font_; 359 return *base_font_;
323 } 360 }
324 } 361 }
325 362
326 void ResourceBundle::ReloadFonts() { 363 void ResourceBundle::ReloadFonts() {
327 base::AutoLock lock_scope(*images_and_fonts_lock_); 364 base::AutoLock lock_scope(*images_and_fonts_lock_);
328 base_font_.reset(); 365 base_font_.reset();
329 LoadFontsIfNecessary(); 366 LoadFontsIfNecessary();
330 } 367 }
331 368
332 ResourceBundle::ResourceBundle() 369 ResourceBundle::ResourceBundle(Delegate* delegate)
333 : images_and_fonts_lock_(new base::Lock), 370 : delegate_(delegate),
371 images_and_fonts_lock_(new base::Lock),
334 locale_resources_data_lock_(new base::Lock) { 372 locale_resources_data_lock_(new base::Lock) {
335 } 373 }
336 374
337 ResourceBundle::~ResourceBundle() { 375 ResourceBundle::~ResourceBundle() {
338 FreeImages(); 376 FreeImages();
339 UnloadLocaleResources(); 377 UnloadLocaleResources();
340 } 378 }
341 379
342 void ResourceBundle::FreeImages() { 380 void ResourceBundle::FreeImages() {
343 STLDeleteContainerPairSecondPointers(images_.begin(),
344 images_.end());
345 images_.clear(); 381 images_.clear();
346 } 382 }
347 383
348 void ResourceBundle::LoadFontsIfNecessary() { 384 void ResourceBundle::LoadFontsIfNecessary() {
349 images_and_fonts_lock_->AssertAcquired(); 385 images_and_fonts_lock_->AssertAcquired();
350 if (!base_font_.get()) { 386 if (!base_font_.get()) {
351 base_font_.reset(new gfx::Font()); 387 if (delegate_) {
388 base_font_.reset(delegate_->GetFont(BaseFont).release());
389 bold_font_.reset(delegate_->GetFont(BoldFont).release());
390 small_font_.reset(delegate_->GetFont(SmallFont).release());
391 medium_font_.reset(delegate_->GetFont(MediumFont).release());
392 medium_bold_font_.reset(delegate_->GetFont(MediumBoldFont).release());
393 large_font_.reset(delegate_->GetFont(LargeFont).release());
394 large_bold_font_.reset(delegate_->GetFont(LargeBoldFont).release());
395 }
352 396
353 bold_font_.reset(new gfx::Font()); 397 if (!base_font_.get())
354 *bold_font_ = 398 base_font_.reset(new gfx::Font());
355 base_font_->DeriveFont(0, base_font_->GetStyle() | gfx::Font::BOLD);
356 399
357 small_font_.reset(new gfx::Font()); 400 if (!bold_font_.get()) {
358 *small_font_ = base_font_->DeriveFont(kSmallFontSizeDelta); 401 bold_font_.reset(new gfx::Font());
402 *bold_font_ =
403 base_font_->DeriveFont(0, base_font_->GetStyle() | gfx::Font::BOLD);
404 }
359 405
360 medium_font_.reset(new gfx::Font()); 406 if (!small_font_.get()) {
361 *medium_font_ = base_font_->DeriveFont(kMediumFontSizeDelta); 407 small_font_.reset(new gfx::Font());
408 *small_font_ = base_font_->DeriveFont(kSmallFontSizeDelta);
409 }
362 410
363 medium_bold_font_.reset(new gfx::Font()); 411 if (!medium_font_.get()) {
364 *medium_bold_font_ = 412 medium_font_.reset(new gfx::Font());
365 base_font_->DeriveFont(kMediumFontSizeDelta, 413 *medium_font_ = base_font_->DeriveFont(kMediumFontSizeDelta);
366 base_font_->GetStyle() | gfx::Font::BOLD); 414 }
367 415
368 large_font_.reset(new gfx::Font()); 416 if (!medium_bold_font_.get()) {
369 *large_font_ = base_font_->DeriveFont(kLargeFontSizeDelta); 417 medium_bold_font_.reset(new gfx::Font());
418 *medium_bold_font_ =
419 base_font_->DeriveFont(kMediumFontSizeDelta,
420 base_font_->GetStyle() | gfx::Font::BOLD);
421 }
370 422
371 large_bold_font_.reset(new gfx::Font()); 423 if (!large_font_.get()) {
372 *large_bold_font_ = 424 large_font_.reset(new gfx::Font());
373 base_font_->DeriveFont(kLargeFontSizeDelta, 425 *large_font_ = base_font_->DeriveFont(kLargeFontSizeDelta);
374 base_font_->GetStyle() | gfx::Font::BOLD); 426 }
427
428 if (!large_bold_font_.get()) {
429 large_bold_font_.reset(new gfx::Font());
430 *large_bold_font_ =
431 base_font_->DeriveFont(kLargeFontSizeDelta,
432 base_font_->GetStyle() | gfx::Font::BOLD);
433 }
375 } 434 }
376 } 435 }
377 436
378 SkBitmap* ResourceBundle::LoadBitmap(const ResourceHandle& data_handle, 437 SkBitmap* ResourceBundle::LoadBitmap(const ResourceHandle& data_handle,
379 int resource_id) { 438 int resource_id) {
380 scoped_refptr<base::RefCountedMemory> memory( 439 scoped_refptr<base::RefCountedMemory> memory(
381 data_handle.GetStaticMemory(resource_id)); 440 data_handle.GetStaticMemory(resource_id));
382 if (!memory) 441 if (!memory)
383 return NULL; 442 return NULL;
384 443
385 SkBitmap bitmap; 444 SkBitmap bitmap;
386 if (gfx::PNGCodec::Decode(memory->front(), memory->size(), &bitmap)) 445 if (gfx::PNGCodec::Decode(memory->front(), memory->size(), &bitmap))
387 return new SkBitmap(bitmap); 446 return new SkBitmap(bitmap);
388 447
389 // 99% of our assets are PNGs, however fallback to JPEG. 448 // 99% of our assets are PNGs, however fallback to JPEG.
390 SkBitmap* allocated_bitmap = 449 SkBitmap* allocated_bitmap =
391 gfx::JPEGCodec::Decode(memory->front(), memory->size()); 450 gfx::JPEGCodec::Decode(memory->front(), memory->size());
392 if (allocated_bitmap) 451 if (allocated_bitmap)
393 return allocated_bitmap; 452 return allocated_bitmap;
394 453
395 NOTREACHED() << "Unable to decode theme image resource " << resource_id; 454 NOTREACHED() << "Unable to decode theme image resource " << resource_id;
396 return NULL; 455 return NULL;
397 } 456 }
398 457
399 gfx::Image* ResourceBundle::GetEmptyImage() { 458 gfx::Image& ResourceBundle::GetEmptyImage() {
400 base::AutoLock lock(*images_and_fonts_lock_); 459 base::AutoLock lock(*images_and_fonts_lock_);
401 460
402 static gfx::Image* empty_image = NULL; 461 if (empty_image_.IsEmpty()) {
403 if (!empty_image) {
404 // The placeholder bitmap is bright red so people notice the problem. 462 // The placeholder bitmap is bright red so people notice the problem.
405 // This bitmap will be leaked, but this code should never be hit.
406 SkBitmap* bitmap = new SkBitmap(); 463 SkBitmap* bitmap = new SkBitmap();
407 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32); 464 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
408 bitmap->allocPixels(); 465 bitmap->allocPixels();
409 bitmap->eraseARGB(255, 255, 0, 0); 466 bitmap->eraseARGB(255, 255, 0, 0);
410 empty_image = new gfx::Image(bitmap); 467 empty_image_ = gfx::Image(bitmap);
411 } 468 }
412 return empty_image; 469 return empty_image_;
413 } 470 }
414 471
415 } // namespace ui 472 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/resource/resource_bundle.h ('k') | ui/base/resource/resource_bundle_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698