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" |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "ui/gfx/safe_integer_conversions.h" | 33 #include "ui/gfx/safe_integer_conversions.h" |
34 #include "ui/gfx/screen.h" | 34 #include "ui/gfx/screen.h" |
35 #include "ui/gfx/size_conversions.h" | 35 #include "ui/gfx/size_conversions.h" |
36 #include "ui/gfx/skbitmap_operations.h" | 36 #include "ui/gfx/skbitmap_operations.h" |
37 | 37 |
38 #if defined(OS_CHROMEOS) | 38 #if defined(OS_CHROMEOS) |
39 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
40 #include "ui/gfx/platform_font_pango.h" | 40 #include "ui/gfx/platform_font_pango.h" |
41 #endif | 41 #endif |
42 | 42 |
| 43 #if defined(OS_WIN) |
| 44 #include "ui/gfx/win/dpi.h" |
| 45 #endif |
| 46 |
| 47 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 48 #include "base/mac/mac_util.h" |
| 49 #endif |
| 50 |
43 namespace ui { | 51 namespace ui { |
44 | 52 |
45 namespace { | 53 namespace { |
46 | 54 |
47 // Font sizes relative to base font. | 55 // Font sizes relative to base font. |
48 const int kSmallFontSizeDelta = -1; | 56 const int kSmallFontSizeDelta = -1; |
49 const int kMediumFontSizeDelta = 3; | 57 const int kMediumFontSizeDelta = 3; |
50 const int kLargeFontSizeDelta = 8; | 58 const int kLargeFontSizeDelta = 8; |
51 | 59 |
52 // PNG-related constants. | 60 // PNG-related constants. |
(...skipping 20 matching lines...) Expand all Loading... |
73 // scaled image is not exactly |scale_factor| * the size of the 1x resource. | 81 // scaled image is not exactly |scale_factor| * the size of the 1x resource. |
74 // When --highlight-missing-scaled-resources flag is specified, scaled 1x images | 82 // When --highlight-missing-scaled-resources flag is specified, scaled 1x images |
75 // are higlighted by blending them with red. | 83 // are higlighted by blending them with red. |
76 class ResourceBundle::ResourceBundleImageSource : public gfx::ImageSkiaSource { | 84 class ResourceBundle::ResourceBundleImageSource : public gfx::ImageSkiaSource { |
77 public: | 85 public: |
78 ResourceBundleImageSource(ResourceBundle* rb, int resource_id) | 86 ResourceBundleImageSource(ResourceBundle* rb, int resource_id) |
79 : rb_(rb), resource_id_(resource_id) {} | 87 : rb_(rb), resource_id_(resource_id) {} |
80 virtual ~ResourceBundleImageSource() {} | 88 virtual ~ResourceBundleImageSource() {} |
81 | 89 |
82 // gfx::ImageSkiaSource overrides: | 90 // gfx::ImageSkiaSource overrides: |
83 virtual gfx::ImageSkiaRep GetImageForScale( | 91 virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE { |
84 ui::ScaleFactor scale_factor) OVERRIDE { | |
85 SkBitmap image; | 92 SkBitmap image; |
86 bool fell_back_to_1x = false; | 93 bool fell_back_to_1x = false; |
| 94 ScaleFactor scale_factor = GetSupportedScaleFactor(scale); |
87 bool found = rb_->LoadBitmap(resource_id_, &scale_factor, | 95 bool found = rb_->LoadBitmap(resource_id_, &scale_factor, |
88 &image, &fell_back_to_1x); | 96 &image, &fell_back_to_1x); |
| 97 // Force to a supported scale. |
| 98 scale = ui::GetImageScale(scale_factor); |
89 if (!found) | 99 if (!found) |
90 return gfx::ImageSkiaRep(); | 100 return gfx::ImageSkiaRep(); |
91 | 101 |
92 if (fell_back_to_1x) { | 102 if (fell_back_to_1x) { |
93 // GRIT fell back to the 100% image, so rescale it to the correct size. | 103 // GRIT fell back to the 100% image, so rescale it to the correct size. |
94 float scale = GetScaleFactorScale(scale_factor); | |
95 image = skia::ImageOperations::Resize( | 104 image = skia::ImageOperations::Resize( |
96 image, | 105 image, |
97 skia::ImageOperations::RESIZE_LANCZOS3, | 106 skia::ImageOperations::RESIZE_LANCZOS3, |
98 gfx::ToCeiledInt(image.width() * scale), | 107 gfx::ToCeiledInt(image.width() * scale), |
99 gfx::ToCeiledInt(image.height() * scale)); | 108 gfx::ToCeiledInt(image.height() * scale)); |
100 // If --highlight-missing-scaled-resources is specified, log the resource | 109 // If --highlight-missing-scaled-resources is specified, log the resource |
101 // id and blend the created resource with red. | 110 // id and blend the created resource with red. |
102 if (ShouldHighlightMissingScaledResources()) { | 111 if (ShouldHighlightMissingScaledResources()) { |
103 LOG(ERROR) << "Missing " << scale << "x scaled resource. id=" | 112 LOG(ERROR) << "Missing " << scale << "x scaled resource. id=" |
104 << resource_id_; | 113 << resource_id_; |
105 | 114 |
106 SkBitmap mask; | 115 SkBitmap mask; |
107 mask.setConfig(SkBitmap::kARGB_8888_Config, | 116 mask.setConfig(SkBitmap::kARGB_8888_Config, |
108 image.width(), image.height()); | 117 image.width(), image.height()); |
109 mask.allocPixels(); | 118 mask.allocPixels(); |
110 mask.eraseColor(SK_ColorRED); | 119 mask.eraseColor(SK_ColorRED); |
111 image = SkBitmapOperations::CreateBlendedBitmap(image, mask, 0.2); | 120 image = SkBitmapOperations::CreateBlendedBitmap(image, mask, 0.2); |
112 } | 121 } |
113 } | 122 } |
114 | 123 |
115 return gfx::ImageSkiaRep(image, scale_factor); | 124 return gfx::ImageSkiaRep(image, scale); |
116 } | 125 } |
117 | 126 |
118 private: | 127 private: |
119 ResourceBundle* rb_; | 128 ResourceBundle* rb_; |
120 const int resource_id_; | 129 const int resource_id_; |
121 | 130 |
122 DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageSource); | 131 DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageSource); |
123 }; | 132 }; |
124 | 133 |
125 // static | 134 // static |
126 std::string ResourceBundle::InitSharedInstanceWithLocale( | 135 std::string ResourceBundle::InitSharedInstanceWithLocale( |
127 const std::string& pref_locale, Delegate* delegate) { | 136 const std::string& pref_locale, Delegate* delegate) { |
128 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; | 137 InitSharedInstance(delegate); |
129 g_shared_instance_ = new ResourceBundle(delegate); | |
130 | |
131 g_shared_instance_->LoadCommonResources(); | 138 g_shared_instance_->LoadCommonResources(); |
132 std::string result = g_shared_instance_->LoadLocaleResources(pref_locale); | 139 std::string result = g_shared_instance_->LoadLocaleResources(pref_locale); |
133 InitDefaultFont(); | 140 InitDefaultFont(); |
134 return result; | 141 return result; |
135 } | 142 } |
136 | 143 |
137 // static | 144 // static |
138 std::string ResourceBundle::InitSharedInstanceLocaleOnly( | 145 std::string ResourceBundle::InitSharedInstanceLocaleOnly( |
139 const std::string& pref_locale, Delegate* delegate) { | 146 const std::string& pref_locale, Delegate* delegate) { |
140 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; | 147 InitSharedInstance(delegate); |
141 g_shared_instance_ = new ResourceBundle(delegate); | |
142 | |
143 std::string result = g_shared_instance_->LoadLocaleResources(pref_locale); | 148 std::string result = g_shared_instance_->LoadLocaleResources(pref_locale); |
144 InitDefaultFont(); | 149 InitDefaultFont(); |
145 return result; | 150 return result; |
146 } | 151 } |
147 | 152 |
148 // static | 153 // static |
149 void ResourceBundle::InitSharedInstanceWithPakFile( | 154 void ResourceBundle::InitSharedInstanceWithPakFile( |
150 base::PlatformFile pak_file, bool should_load_common_resources) { | 155 base::PlatformFile pak_file, bool should_load_common_resources) { |
151 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; | 156 InitSharedInstance(NULL); |
152 g_shared_instance_ = new ResourceBundle(NULL); | |
153 | |
154 if (should_load_common_resources) | 157 if (should_load_common_resources) |
155 g_shared_instance_->LoadCommonResources(); | 158 g_shared_instance_->LoadCommonResources(); |
156 | 159 |
157 scoped_ptr<DataPack> data_pack( | 160 scoped_ptr<DataPack> data_pack( |
158 new DataPack(SCALE_FACTOR_100P)); | 161 new DataPack(SCALE_FACTOR_100P)); |
159 if (!data_pack->LoadFromFile(pak_file)) { | 162 if (!data_pack->LoadFromFile(pak_file)) { |
160 NOTREACHED() << "failed to load pak file"; | 163 NOTREACHED() << "failed to load pak file"; |
161 return; | 164 return; |
162 } | 165 } |
163 g_shared_instance_->locale_resources_data_.reset(data_pack.release()); | 166 g_shared_instance_->locale_resources_data_.reset(data_pack.release()); |
164 InitDefaultFont(); | 167 InitDefaultFont(); |
165 } | 168 } |
166 | 169 |
167 // static | 170 // static |
168 void ResourceBundle::InitSharedInstanceWithPakPath(const base::FilePath& path) { | 171 void ResourceBundle::InitSharedInstanceWithPakPath(const base::FilePath& path) { |
169 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; | 172 InitSharedInstance(NULL); |
170 g_shared_instance_ = new ResourceBundle(NULL); | |
171 | |
172 g_shared_instance_->LoadTestResources(path, path); | 173 g_shared_instance_->LoadTestResources(path, path); |
173 | 174 |
174 InitDefaultFont(); | 175 InitDefaultFont(); |
175 } | 176 } |
176 | 177 |
177 // static | 178 // static |
178 void ResourceBundle::CleanupSharedInstance() { | 179 void ResourceBundle::CleanupSharedInstance() { |
179 if (g_shared_instance_) { | 180 if (g_shared_instance_) { |
180 delete g_shared_instance_; | 181 delete g_shared_instance_; |
181 g_shared_instance_ = NULL; | 182 g_shared_instance_ = NULL; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 } | 335 } |
335 | 336 |
336 gfx::Image image; | 337 gfx::Image image; |
337 if (delegate_) | 338 if (delegate_) |
338 image = delegate_->GetImageNamed(resource_id); | 339 image = delegate_->GetImageNamed(resource_id); |
339 | 340 |
340 if (image.IsEmpty()) { | 341 if (image.IsEmpty()) { |
341 DCHECK(!data_packs_.empty()) << | 342 DCHECK(!data_packs_.empty()) << |
342 "Missing call to SetResourcesDataDLL?"; | 343 "Missing call to SetResourcesDataDLL?"; |
343 | 344 |
| 345 #if defined(OS_CHROMEOS) |
| 346 ui::ScaleFactor scale_factor_to_load = GetMaxScaleFactor(); |
| 347 #else |
| 348 ui::ScaleFactor scale_factor_to_load = ui::SCALE_FACTOR_100P; |
| 349 #endif |
| 350 |
| 351 float scale = GetImageScale(scale_factor_to_load); |
344 // TODO(oshima): Consider reading the image size from png IHDR chunk and | 352 // TODO(oshima): Consider reading the image size from png IHDR chunk and |
345 // skip decoding here and remove #ifdef below. | 353 // skip decoding here and remove #ifdef below. |
346 // ResourceBundle::GetSharedInstance() is destroyed after the | 354 // ResourceBundle::GetSharedInstance() is destroyed after the |
347 // BrowserMainLoop has finished running. |image_skia| is guaranteed to be | 355 // BrowserMainLoop has finished running. |image_skia| is guaranteed to be |
348 // destroyed before the resource bundle is destroyed. | 356 // destroyed before the resource bundle is destroyed. |
349 #if defined(OS_CHROMEOS) | |
350 ui::ScaleFactor scale_factor_to_load = ui::GetMaxScaleFactor(); | |
351 #else | |
352 ui::ScaleFactor scale_factor_to_load = ui::SCALE_FACTOR_100P; | |
353 #endif | |
354 gfx::ImageSkia image_skia(new ResourceBundleImageSource(this, resource_id), | 357 gfx::ImageSkia image_skia(new ResourceBundleImageSource(this, resource_id), |
355 scale_factor_to_load); | 358 scale); |
356 if (image_skia.isNull()) { | 359 if (image_skia.isNull()) { |
357 LOG(WARNING) << "Unable to load image with id " << resource_id; | 360 LOG(WARNING) << "Unable to load image with id " << resource_id; |
358 NOTREACHED(); // Want to assert in debug mode. | 361 NOTREACHED(); // Want to assert in debug mode. |
359 // The load failed to retrieve the image; show a debugging red square. | 362 // The load failed to retrieve the image; show a debugging red square. |
360 return GetEmptyImage(); | 363 return GetEmptyImage(); |
361 } | 364 } |
362 image_skia.SetReadOnly(); | 365 image_skia.SetReadOnly(); |
363 image = gfx::Image(image_skia); | 366 image = gfx::Image(image_skia); |
364 } | 367 } |
365 | 368 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 const gfx::Font& ResourceBundle::GetFont(FontStyle style) { | 506 const gfx::Font& ResourceBundle::GetFont(FontStyle style) { |
504 return GetFontList(style).GetPrimaryFont(); | 507 return GetFontList(style).GetPrimaryFont(); |
505 } | 508 } |
506 | 509 |
507 void ResourceBundle::ReloadFonts() { | 510 void ResourceBundle::ReloadFonts() { |
508 base::AutoLock lock_scope(*images_and_fonts_lock_); | 511 base::AutoLock lock_scope(*images_and_fonts_lock_); |
509 base_font_list_.reset(); | 512 base_font_list_.reset(); |
510 LoadFontsIfNecessary(); | 513 LoadFontsIfNecessary(); |
511 } | 514 } |
512 | 515 |
| 516 ScaleFactor ResourceBundle::GetMaxScaleFactor() const { |
| 517 #if defined(OS_CHROMEOS) |
| 518 return max_scale_factor_; |
| 519 #else |
| 520 return GetSupportedScaleFactors().back(); |
| 521 #endif |
| 522 } |
| 523 |
513 ResourceBundle::ResourceBundle(Delegate* delegate) | 524 ResourceBundle::ResourceBundle(Delegate* delegate) |
514 : delegate_(delegate), | 525 : delegate_(delegate), |
515 images_and_fonts_lock_(new base::Lock), | 526 images_and_fonts_lock_(new base::Lock), |
516 locale_resources_data_lock_(new base::Lock), | 527 locale_resources_data_lock_(new base::Lock), |
517 max_scale_factor_(SCALE_FACTOR_100P) { | 528 max_scale_factor_(SCALE_FACTOR_100P) { |
518 } | 529 } |
519 | 530 |
520 ResourceBundle::~ResourceBundle() { | 531 ResourceBundle::~ResourceBundle() { |
521 FreeImages(); | 532 FreeImages(); |
522 UnloadLocaleResources(); | 533 UnloadLocaleResources(); |
523 } | 534 } |
524 | 535 |
| 536 // static |
| 537 void ResourceBundle::InitSharedInstance(Delegate* delegate) { |
| 538 DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice"; |
| 539 g_shared_instance_ = new ResourceBundle(delegate); |
| 540 static std::vector<ScaleFactor> supported_scale_factors; |
| 541 #if !defined(OS_IOS) |
| 542 // On platforms other than iOS, 100P is always a supported scale factor. |
| 543 supported_scale_factors.push_back(SCALE_FACTOR_100P); |
| 544 #endif |
| 545 |
| 546 #if defined(OS_ANDROID) |
| 547 const gfx::Display display = |
| 548 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); |
| 549 const float display_density = display.device_scale_factor(); |
| 550 const ScaleFactor closest = FindClosestScaleFactorUnsafe(display_density); |
| 551 if (closest != SCALE_FACTOR_100P) |
| 552 supported_scale_factors.push_back(closest); |
| 553 #elif defined(OS_IOS) |
| 554 gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); |
| 555 if (display.device_scale_factor() > 1.0) { |
| 556 DCHECK_EQ(2.0, display.device_scale_factor()); |
| 557 supported_scale_factors.push_back(SCALE_FACTOR_200P); |
| 558 } else { |
| 559 supported_scale_factors.push_back(SCALE_FACTOR_100P); |
| 560 } |
| 561 #elif defined(OS_MACOSX) |
| 562 if (base::mac::IsOSLionOrLater()) |
| 563 supported_scale_factors.push_back(SCALE_FACTOR_200P); |
| 564 #elif defined(OS_WIN) |
| 565 // Have high-DPI resources for 140% and 180% scaling on Windows based on |
| 566 // default scaling for Metro mode. Round to nearest supported scale in |
| 567 // all cases. |
| 568 if (gfx::IsInHighDPIMode()) { |
| 569 supported_scale_factors.push_back(SCALE_FACTOR_140P); |
| 570 supported_scale_factors.push_back(SCALE_FACTOR_180P); |
| 571 } |
| 572 #elif defined(OS_CHROMEOS) |
| 573 // TODO(oshima): Include 200P only if the device support 200P |
| 574 supported_scale_factors.push_back(SCALE_FACTOR_200P); |
| 575 #endif |
| 576 ui::SetSupportedScaleFactors(supported_scale_factors); |
| 577 } |
| 578 |
525 void ResourceBundle::FreeImages() { | 579 void ResourceBundle::FreeImages() { |
526 images_.clear(); | 580 images_.clear(); |
527 } | 581 } |
528 | 582 |
529 void ResourceBundle::AddDataPackFromPathInternal(const base::FilePath& path, | 583 void ResourceBundle::AddDataPackFromPathInternal(const base::FilePath& path, |
530 ScaleFactor scale_factor, | 584 ScaleFactor scale_factor, |
531 bool optional) { | 585 bool optional) { |
532 // Do not pass an empty |path| value to this method. If the absolute path is | 586 // Do not pass an empty |path| value to this method. If the absolute path is |
533 // unknown pass just the pack file name. | 587 // unknown pass just the pack file name. |
534 DCHECK(!path.empty()); | 588 DCHECK(!path.empty()); |
(...skipping 12 matching lines...) Expand all Loading... |
547 AddDataPack(data_pack.release()); | 601 AddDataPack(data_pack.release()); |
548 } else if (!optional) { | 602 } else if (!optional) { |
549 LOG(ERROR) << "Failed to load " << pack_path.value() | 603 LOG(ERROR) << "Failed to load " << pack_path.value() |
550 << "\nSome features may not be available."; | 604 << "\nSome features may not be available."; |
551 } | 605 } |
552 } | 606 } |
553 | 607 |
554 void ResourceBundle::AddDataPack(DataPack* data_pack) { | 608 void ResourceBundle::AddDataPack(DataPack* data_pack) { |
555 data_packs_.push_back(data_pack); | 609 data_packs_.push_back(data_pack); |
556 | 610 |
557 if (GetScaleFactorScale(data_pack->GetScaleFactor()) > | 611 if (GetImageScale(data_pack->GetScaleFactor()) > |
558 GetScaleFactorScale(max_scale_factor_)) | 612 GetImageScale(max_scale_factor_)) |
559 max_scale_factor_ = data_pack->GetScaleFactor(); | 613 max_scale_factor_ = data_pack->GetScaleFactor(); |
560 } | 614 } |
561 | 615 |
562 void ResourceBundle::LoadFontsIfNecessary() { | 616 void ResourceBundle::LoadFontsIfNecessary() { |
563 images_and_fonts_lock_->AssertAcquired(); | 617 images_and_fonts_lock_->AssertAcquired(); |
564 if (!base_font_list_.get()) { | 618 if (!base_font_list_.get()) { |
565 if (delegate_) { | 619 if (delegate_) { |
566 base_font_list_ = GetFontListFromDelegate(BaseFont); | 620 base_font_list_ = GetFontListFromDelegate(BaseFont); |
567 bold_font_list_ = GetFontListFromDelegate(BoldFont); | 621 bold_font_list_ = GetFontListFromDelegate(BoldFont); |
568 small_font_list_ = GetFontListFromDelegate(SmallFont); | 622 small_font_list_ = GetFontListFromDelegate(SmallFont); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 // static | 798 // static |
745 bool ResourceBundle::DecodePNG(const unsigned char* buf, | 799 bool ResourceBundle::DecodePNG(const unsigned char* buf, |
746 size_t size, | 800 size_t size, |
747 SkBitmap* bitmap, | 801 SkBitmap* bitmap, |
748 bool* fell_back_to_1x) { | 802 bool* fell_back_to_1x) { |
749 *fell_back_to_1x = PNGContainsFallbackMarker(buf, size); | 803 *fell_back_to_1x = PNGContainsFallbackMarker(buf, size); |
750 return gfx::PNGCodec::Decode(buf, size, bitmap); | 804 return gfx::PNGCodec::Decode(buf, size, bitmap); |
751 } | 805 } |
752 | 806 |
753 } // namespace ui | 807 } // namespace ui |
OLD | NEW |