OLD | NEW |
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/layout.h" |
22 #include "ui/base/resource/data_pack.h" | 23 #include "ui/base/resource/data_pack.h" |
23 #include "ui/base/ui_base_paths.h" | 24 #include "ui/base/ui_base_paths.h" |
24 #include "ui/base/ui_base_switches.h" | 25 #include "ui/base/ui_base_switches.h" |
25 #include "ui/gfx/codec/jpeg_codec.h" | 26 #include "ui/gfx/codec/jpeg_codec.h" |
26 #include "ui/gfx/codec/png_codec.h" | 27 #include "ui/gfx/codec/png_codec.h" |
27 | 28 |
28 namespace ui { | 29 namespace ui { |
29 | 30 |
30 namespace { | 31 namespace { |
31 | 32 |
(...skipping 20 matching lines...) Expand all Loading... |
52 | 53 |
53 g_shared_instance_->LoadCommonResources(); | 54 g_shared_instance_->LoadCommonResources(); |
54 return g_shared_instance_->LoadLocaleResources(pref_locale); | 55 return g_shared_instance_->LoadLocaleResources(pref_locale); |
55 } | 56 } |
56 | 57 |
57 // static | 58 // static |
58 void ResourceBundle::InitSharedInstanceWithPakFile(const FilePath& path) { | 59 void ResourceBundle::InitSharedInstanceWithPakFile(const FilePath& path) { |
59 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; | 60 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; |
60 g_shared_instance_ = new ResourceBundle(NULL); | 61 g_shared_instance_ = new ResourceBundle(NULL); |
61 | 62 |
62 g_shared_instance_->LoadTestResources(path); | 63 g_shared_instance_->LoadTestResources(path, path); |
63 } | 64 } |
64 | 65 |
65 // static | 66 // static |
66 void ResourceBundle::CleanupSharedInstance() { | 67 void ResourceBundle::CleanupSharedInstance() { |
67 if (g_shared_instance_) { | 68 if (g_shared_instance_) { |
68 delete g_shared_instance_; | 69 delete g_shared_instance_; |
69 g_shared_instance_ = NULL; | 70 g_shared_instance_ = NULL; |
70 } | 71 } |
71 } | 72 } |
72 | 73 |
73 // static | 74 // static |
74 bool ResourceBundle::HasSharedInstance() { | 75 bool ResourceBundle::HasSharedInstance() { |
75 return g_shared_instance_ != NULL; | 76 return g_shared_instance_ != NULL; |
76 } | 77 } |
77 | 78 |
78 // static | 79 // static |
79 ResourceBundle& ResourceBundle::GetSharedInstance() { | 80 ResourceBundle& ResourceBundle::GetSharedInstance() { |
80 // Must call InitSharedInstance before this function. | 81 // Must call InitSharedInstance before this function. |
81 CHECK(g_shared_instance_ != NULL); | 82 CHECK(g_shared_instance_ != NULL); |
82 return *g_shared_instance_; | 83 return *g_shared_instance_; |
83 } | 84 } |
84 | 85 |
85 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { | 86 bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { |
86 return !GetLocaleFilePath(locale).empty(); | 87 return !GetLocaleFilePath(locale).empty(); |
87 } | 88 } |
88 | 89 |
89 void ResourceBundle::AddDataPack(const FilePath& path, float scale_factor) { | 90 void ResourceBundle::AddDataPack(const FilePath& path, |
| 91 ScaleFactor scale_factor) { |
90 // Do not pass an empty |path| value to this method. If the absolute path is | 92 // Do not pass an empty |path| value to this method. If the absolute path is |
91 // unknown pass just the pack file name. | 93 // unknown pass just the pack file name. |
92 DCHECK(!path.empty()); | 94 DCHECK(!path.empty()); |
93 | 95 |
94 FilePath pack_path = path; | 96 FilePath pack_path = path; |
95 if (delegate_) | 97 if (delegate_) |
96 pack_path = delegate_->GetPathForResourcePack(pack_path, scale_factor); | 98 pack_path = delegate_->GetPathForResourcePack(pack_path, scale_factor); |
97 | 99 |
98 // Don't try to load empty values or values that are not absolute paths. | 100 // Don't try to load empty values or values that are not absolute paths. |
99 if (pack_path.empty() || !pack_path.IsAbsolute()) | 101 if (pack_path.empty() || !pack_path.IsAbsolute()) |
100 return; | 102 return; |
101 | 103 |
102 scoped_ptr<DataPack> data_pack( | 104 scoped_ptr<DataPack> data_pack( |
103 new DataPack(ResourceHandle::kScaleFactor100x)); | 105 new DataPack(scale_factor)); |
104 if (data_pack->Load(pack_path)) { | 106 if (data_pack->Load(pack_path)) { |
105 data_packs_.push_back(data_pack.release()); | 107 data_packs_.push_back(data_pack.release()); |
106 } else { | 108 } else { |
107 LOG(ERROR) << "Failed to load " << pack_path.value() | 109 LOG(ERROR) << "Failed to load " << pack_path.value() |
108 << "\nSome features may not be available."; | 110 << "\nSome features may not be available."; |
109 } | 111 } |
110 } | 112 } |
111 | 113 |
112 #if !defined(OS_MACOSX) | 114 #if !defined(OS_MACOSX) |
113 FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale) { | 115 FilePath ResourceBundle::GetLocaleFilePath(const std::string& app_locale) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 locale_file_path = GetLocaleFilePath(app_locale); | 158 locale_file_path = GetLocaleFilePath(app_locale); |
157 } | 159 } |
158 } | 160 } |
159 | 161 |
160 if (locale_file_path.empty()) { | 162 if (locale_file_path.empty()) { |
161 // It's possible that there is no locale.pak. | 163 // It's possible that there is no locale.pak. |
162 return std::string(); | 164 return std::string(); |
163 } | 165 } |
164 | 166 |
165 scoped_ptr<DataPack> data_pack( | 167 scoped_ptr<DataPack> data_pack( |
166 new DataPack(ResourceHandle::kScaleFactor100x)); | 168 new DataPack(SCALE_FACTOR_100P)); |
167 if (!data_pack->Load(locale_file_path)) { | 169 if (!data_pack->Load(locale_file_path)) { |
168 UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError", | 170 UMA_HISTOGRAM_ENUMERATION("ResourceBundle.LoadLocaleResourcesError", |
169 logging::GetLastSystemErrorCode(), 16000); | 171 logging::GetLastSystemErrorCode(), 16000); |
170 NOTREACHED() << "failed to load locale.pak"; | 172 NOTREACHED() << "failed to load locale.pak"; |
171 return std::string(); | 173 return std::string(); |
172 } | 174 } |
173 | 175 |
174 locale_resources_data_.reset(data_pack.release()); | 176 locale_resources_data_.reset(data_pack.release()); |
175 return app_locale; | 177 return app_locale; |
176 } | 178 } |
177 | 179 |
178 void ResourceBundle::LoadTestResources(const FilePath& path) { | 180 void ResourceBundle::LoadTestResources(const FilePath& path, |
| 181 const FilePath& locale_path) { |
179 // Use the given resource pak for both common and localized resources. | 182 // Use the given resource pak for both common and localized resources. |
180 scoped_ptr<DataPack> data_pack( | 183 scoped_ptr<DataPack> data_pack( |
181 new DataPack(ResourceHandle::kScaleFactor100x)); | 184 new DataPack(SCALE_FACTOR_100P)); |
182 if (data_pack->Load(path)) | 185 if (!path.empty() && data_pack->Load(path)) |
183 data_packs_.push_back(data_pack.release()); | 186 data_packs_.push_back(data_pack.release()); |
184 | 187 |
185 data_pack.reset(new DataPack(ResourceHandle::kScaleFactor100x)); | 188 data_pack.reset(new DataPack(ui::kScaleFactorNone)); |
186 if (data_pack->Load(path)) | 189 if (!locale_path.empty() && data_pack->Load(locale_path)) { |
187 locale_resources_data_.reset(data_pack.release()); | 190 locale_resources_data_.reset(data_pack.release()); |
| 191 } else { |
| 192 locale_resources_data_.reset( |
| 193 new DataPack(ui::kScaleFactorNone)); |
| 194 } |
188 } | 195 } |
189 | 196 |
190 void ResourceBundle::UnloadLocaleResources() { | 197 void ResourceBundle::UnloadLocaleResources() { |
191 locale_resources_data_.reset(); | 198 locale_resources_data_.reset(); |
192 } | 199 } |
193 | 200 |
194 void ResourceBundle::OverrideLocalePakForTest(const FilePath& pak_path) { | 201 void ResourceBundle::OverrideLocalePakForTest(const FilePath& pak_path) { |
195 overridden_pak_path_ = pak_path; | 202 overridden_pak_path_ = pak_path; |
196 } | 203 } |
197 | 204 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 | 268 |
262 images_[resource_id] = image; | 269 images_[resource_id] = image; |
263 return images_[resource_id]; | 270 return images_[resource_id]; |
264 } | 271 } |
265 | 272 |
266 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { | 273 gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { |
267 return GetNativeImageNamed(resource_id, RTL_DISABLED); | 274 return GetNativeImageNamed(resource_id, RTL_DISABLED); |
268 } | 275 } |
269 | 276 |
270 base::RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytes( | 277 base::RefCountedStaticMemory* ResourceBundle::LoadDataResourceBytes( |
271 int resource_id) const { | 278 int resource_id, |
| 279 ScaleFactor scale_factor) const { |
272 base::RefCountedStaticMemory* bytes = NULL; | 280 base::RefCountedStaticMemory* bytes = NULL; |
273 if (delegate_) | 281 if (delegate_) |
274 bytes = delegate_->LoadDataResourceBytes(resource_id); | 282 bytes = delegate_->LoadDataResourceBytes(resource_id, scale_factor); |
275 | 283 |
276 if (!bytes) { | 284 if (!bytes) { |
277 for (size_t i = 0; i < data_packs_.size() && !bytes; ++i) | 285 base::StringPiece data = GetRawDataResource(resource_id, scale_factor); |
278 bytes = data_packs_[i]->GetStaticMemory(resource_id); | 286 if (!data.empty()) { |
| 287 bytes = new base::RefCountedStaticMemory( |
| 288 reinterpret_cast<const unsigned char*>(data.data()), data.length()); |
| 289 } |
279 } | 290 } |
280 | 291 |
281 return bytes; | 292 return bytes; |
282 } | 293 } |
283 | 294 |
284 base::StringPiece ResourceBundle::GetRawDataResource(int resource_id) const { | 295 base::StringPiece ResourceBundle::GetRawDataResource( |
| 296 int resource_id, |
| 297 ScaleFactor scale_factor) const { |
285 base::StringPiece data; | 298 base::StringPiece data; |
286 if (delegate_ && delegate_->GetRawDataResource(resource_id, &data)) | 299 if (delegate_ && |
| 300 delegate_->GetRawDataResource(resource_id, scale_factor, &data)) |
287 return data; | 301 return data; |
288 | 302 |
289 DCHECK(locale_resources_data_.get()); | 303 DCHECK(locale_resources_data_.get()); |
290 if (locale_resources_data_->GetStringPiece(resource_id, &data)) | 304 if (locale_resources_data_->GetStringPiece(resource_id, &data)) |
291 return data; | 305 return data; |
292 | 306 |
293 for (size_t i = 0; i < data_packs_.size(); ++i) { | 307 if (scale_factor != ui::SCALE_FACTOR_100P) { |
294 if (data_packs_[i]->GetStringPiece(resource_id, &data)) | 308 for (size_t i = 0; i < data_packs_.size(); i++) { |
| 309 if (data_packs_[i]->GetScaleFactor() == scale_factor && |
| 310 data_packs_[i]->GetStringPiece(resource_id, &data)) |
| 311 return data; |
| 312 } |
| 313 } |
| 314 for (size_t i = 0; i < data_packs_.size(); i++) { |
| 315 if (data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_100P && |
| 316 data_packs_[i]->GetStringPiece(resource_id, &data)) |
295 return data; | 317 return data; |
296 } | 318 } |
297 | 319 |
298 return base::StringPiece(); | 320 return base::StringPiece(); |
299 } | 321 } |
300 | 322 |
301 string16 ResourceBundle::GetLocalizedString(int message_id) { | 323 string16 ResourceBundle::GetLocalizedString(int message_id) { |
302 string16 string; | 324 string16 string; |
303 if (delegate_ && delegate_->GetLocalizedString(message_id, &string)) | 325 if (delegate_ && delegate_->GetLocalizedString(message_id, &string)) |
304 return string; | 326 return string; |
305 | 327 |
306 // Ensure that ReloadLocaleResources() doesn't drop the resources while | 328 // Ensure that ReloadLocaleResources() doesn't drop the resources while |
307 // we're using them. | 329 // we're using them. |
308 base::AutoLock lock_scope(*locale_resources_data_lock_); | 330 base::AutoLock lock_scope(*locale_resources_data_lock_); |
309 | 331 |
310 // If for some reason we were unable to load the resources , return an empty | 332 // If for some reason we were unable to load the resources , return an empty |
311 // string (better than crashing). | 333 // string (better than crashing). |
312 if (!locale_resources_data_.get()) { | 334 if (!locale_resources_data_.get()) { |
313 LOG(WARNING) << "locale resources are not loaded"; | 335 LOG(WARNING) << "locale resources are not loaded"; |
314 return string16(); | 336 return string16(); |
315 } | 337 } |
316 | 338 |
317 base::StringPiece data; | 339 base::StringPiece data; |
318 if (!locale_resources_data_->GetStringPiece(message_id, &data)) { | 340 if (!locale_resources_data_->GetStringPiece(message_id, &data)) { |
319 // Fall back on the main data pack (shouldn't be any strings here except in | 341 // Fall back on the main data pack (shouldn't be any strings here except in |
320 // unittests). | 342 // unittests). |
321 data = GetRawDataResource(message_id); | 343 data = GetRawDataResource(message_id, ui::kScaleFactorNone); |
322 if (data.empty()) { | 344 if (data.empty()) { |
323 NOTREACHED() << "unable to find resource: " << message_id; | 345 NOTREACHED() << "unable to find resource: " << message_id; |
324 return string16(); | 346 return string16(); |
325 } | 347 } |
326 } | 348 } |
327 | 349 |
328 // Strings should not be loaded from a data pack that contains binary data. | 350 // Strings should not be loaded from a data pack that contains binary data. |
329 ResourceHandle::TextEncodingType encoding = | 351 ResourceHandle::TextEncodingType encoding = |
330 locale_resources_data_->GetTextEncodingType(); | 352 locale_resources_data_->GetTextEncodingType(); |
331 DCHECK(encoding == ResourceHandle::UTF16 || encoding == ResourceHandle::UTF8) | 353 DCHECK(encoding == ResourceHandle::UTF16 || encoding == ResourceHandle::UTF8) |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 SkBitmap* bitmap = new SkBitmap(); | 490 SkBitmap* bitmap = new SkBitmap(); |
469 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32); | 491 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32); |
470 bitmap->allocPixels(); | 492 bitmap->allocPixels(); |
471 bitmap->eraseARGB(255, 255, 0, 0); | 493 bitmap->eraseARGB(255, 255, 0, 0); |
472 empty_image_ = gfx::Image(bitmap); | 494 empty_image_ = gfx::Image(bitmap); |
473 } | 495 } |
474 return empty_image_; | 496 return empty_image_; |
475 } | 497 } |
476 | 498 |
477 } // namespace ui | 499 } // namespace ui |
OLD | NEW |