ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / ui / base / resource / resource_bundle_unittest.cc
blob5aa5017c9662b8ab18726f91f36bbe7719a9cb3f
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
3 // found in the LICENSE file.
5 #include "ui/base/resource/resource_bundle.h"
7 #include "base/base_paths.h"
8 #include "base/big_endian.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted_memory.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/skia/include/core/SkBitmap.h"
18 #include "ui/base/layout.h"
19 #include "ui/base/resource/data_pack.h"
20 #include "ui/gfx/codec/png_codec.h"
21 #include "ui/gfx/font_list.h"
22 #include "ui/gfx/image/image_skia.h"
23 #include "ui/resources/grit/ui_resources.h"
24 #include "ui/strings/grit/app_locale_settings.h"
26 #if defined(OS_WIN)
27 #include "ui/gfx/win/dpi.h"
28 #endif
30 using ::testing::_;
31 using ::testing::Between;
32 using ::testing::Property;
33 using ::testing::Return;
34 using ::testing::ReturnArg;
36 namespace ui {
38 extern const char kSamplePakContents[];
39 extern const size_t kSamplePakSize;
40 extern const char kSamplePakContents2x[];
41 extern const size_t kSamplePakSize2x;
42 extern const char kEmptyPakContents[];
43 extern const size_t kEmptyPakSize;
45 namespace {
47 const unsigned char kPngMagic[8] = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 };
48 const size_t kPngChunkMetadataSize = 12;
49 const unsigned char kPngIHDRChunkType[4] = { 'I', 'H', 'D', 'R' };
51 // Custom chunk that GRIT adds to PNG to indicate that it could not find a
52 // bitmap at the requested scale factor and fell back to 1x.
53 const unsigned char kPngScaleChunk[12] = { 0x00, 0x00, 0x00, 0x00,
54 'c', 's', 'C', 'l',
55 0xc1, 0x30, 0x60, 0x4d };
57 // Mock for the ResourceBundle::Delegate class.
58 class MockResourceBundleDelegate : public ui::ResourceBundle::Delegate {
59 public:
60 MockResourceBundleDelegate() {
62 virtual ~MockResourceBundleDelegate() {
65 MOCK_METHOD2(GetPathForResourcePack, base::FilePath(
66 const base::FilePath& pack_path, ui::ScaleFactor scale_factor));
67 MOCK_METHOD2(GetPathForLocalePack, base::FilePath(
68 const base::FilePath& pack_path, const std::string& locale));
69 MOCK_METHOD1(GetImageNamed, gfx::Image(int resource_id));
70 MOCK_METHOD2(GetNativeImageNamed,
71 gfx::Image(int resource_id,
72 ui::ResourceBundle::ImageRTL rtl));
73 MOCK_METHOD2(LoadDataResourceBytes,
74 base::RefCountedStaticMemory*(int resource_id,
75 ui::ScaleFactor scale_factor));
76 MOCK_METHOD2(GetRawDataResourceMock, base::StringPiece(
77 int resource_id,
78 ui::ScaleFactor scale_factor));
79 virtual bool GetRawDataResource(int resource_id,
80 ui::ScaleFactor scale_factor,
81 base::StringPiece* value) override {
82 *value = GetRawDataResourceMock(resource_id, scale_factor);
83 return true;
85 MOCK_METHOD1(GetLocalizedStringMock, base::string16(int message_id));
86 virtual bool GetLocalizedString(int message_id,
87 base::string16* value) override {
88 *value = GetLocalizedStringMock(message_id);
89 return true;
91 MOCK_METHOD1(GetFontMock,
92 gfx::Font*(ui::ResourceBundle::FontStyle style));
93 virtual scoped_ptr<gfx::Font> GetFont(
94 ui::ResourceBundle::FontStyle style) override {
95 return make_scoped_ptr(GetFontMock(style));
99 // Returns |bitmap_data| with |custom_chunk| inserted after the IHDR chunk.
100 void AddCustomChunk(const base::StringPiece& custom_chunk,
101 std::vector<unsigned char>* bitmap_data) {
102 EXPECT_LT(arraysize(kPngMagic) + kPngChunkMetadataSize, bitmap_data->size());
103 EXPECT_TRUE(std::equal(
104 bitmap_data->begin(),
105 bitmap_data->begin() + arraysize(kPngMagic),
106 kPngMagic));
107 std::vector<unsigned char>::iterator ihdr_start =
108 bitmap_data->begin() + arraysize(kPngMagic);
109 char ihdr_length_data[sizeof(uint32)];
110 for (size_t i = 0; i < sizeof(uint32); ++i)
111 ihdr_length_data[i] = *(ihdr_start + i);
112 uint32 ihdr_chunk_length = 0;
113 base::ReadBigEndian(reinterpret_cast<char*>(ihdr_length_data),
114 &ihdr_chunk_length);
115 EXPECT_TRUE(std::equal(
116 ihdr_start + sizeof(uint32),
117 ihdr_start + sizeof(uint32) + sizeof(kPngIHDRChunkType),
118 kPngIHDRChunkType));
120 bitmap_data->insert(ihdr_start + kPngChunkMetadataSize + ihdr_chunk_length,
121 custom_chunk.begin(), custom_chunk.end());
124 // Creates datapack at |path| with a single bitmap at resource ID 3
125 // which is |edge_size|x|edge_size| pixels.
126 // If |custom_chunk| is non empty, adds it after the IHDR chunk
127 // in the encoded bitmap data.
128 void CreateDataPackWithSingleBitmap(const base::FilePath& path,
129 int edge_size,
130 const base::StringPiece& custom_chunk) {
131 SkBitmap bitmap;
132 bitmap.allocN32Pixels(edge_size, edge_size);
133 bitmap.eraseColor(SK_ColorWHITE);
134 std::vector<unsigned char> bitmap_data;
135 EXPECT_TRUE(gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data));
137 if (custom_chunk.size() > 0)
138 AddCustomChunk(custom_chunk, &bitmap_data);
140 std::map<uint16, base::StringPiece> resources;
141 resources[3u] = base::StringPiece(
142 reinterpret_cast<const char*>(&bitmap_data[0]), bitmap_data.size());
143 DataPack::WritePack(path, resources, ui::DataPack::BINARY);
146 } // namespace
148 class ResourceBundleTest : public testing::Test {
149 public:
150 ResourceBundleTest() : resource_bundle_(NULL) {
153 ~ResourceBundleTest() override {}
155 // Overridden from testing::Test:
156 void TearDown() override { delete resource_bundle_; }
158 // Returns new ResoureBundle with the specified |delegate|. The
159 // ResourceBundleTest class manages the lifetime of the returned
160 // ResourceBundle.
161 ResourceBundle* CreateResourceBundle(ResourceBundle::Delegate* delegate) {
162 DCHECK(!resource_bundle_);
164 resource_bundle_ = new ResourceBundle(delegate);
165 return resource_bundle_;
168 protected:
169 ResourceBundle* resource_bundle_;
171 private:
172 DISALLOW_COPY_AND_ASSIGN(ResourceBundleTest);
175 TEST_F(ResourceBundleTest, DelegateGetPathForResourcePack) {
176 MockResourceBundleDelegate delegate;
177 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
179 base::FilePath pack_path(FILE_PATH_LITERAL("/path/to/test_path.pak"));
180 ui::ScaleFactor pack_scale_factor = ui::SCALE_FACTOR_200P;
182 EXPECT_CALL(delegate,
183 GetPathForResourcePack(
184 Property(&base::FilePath::value, pack_path.value()),
185 pack_scale_factor))
186 .Times(1)
187 .WillOnce(Return(pack_path));
189 resource_bundle->AddDataPackFromPath(pack_path, pack_scale_factor);
192 #if defined(OS_LINUX)
193 // Fails consistently on Linux: crbug.com/161902
194 #define MAYBE_DelegateGetPathForLocalePack DISABLED_DelegateGetPathForLocalePack
195 #else
196 #define MAYBE_DelegateGetPathForLocalePack DelegateGetPathForLocalePack
197 #endif
198 TEST_F(ResourceBundleTest, MAYBE_DelegateGetPathForLocalePack) {
199 MockResourceBundleDelegate delegate;
200 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
202 std::string locale = "en-US";
204 // Cancel the load.
205 EXPECT_CALL(delegate, GetPathForLocalePack(_, locale))
206 .Times(2)
207 .WillRepeatedly(Return(base::FilePath()))
208 .RetiresOnSaturation();
210 EXPECT_FALSE(resource_bundle->LocaleDataPakExists(locale));
211 EXPECT_EQ("", resource_bundle->LoadLocaleResources(locale));
213 // Allow the load to proceed.
214 EXPECT_CALL(delegate, GetPathForLocalePack(_, locale))
215 .Times(2)
216 .WillRepeatedly(ReturnArg<0>());
218 EXPECT_TRUE(resource_bundle->LocaleDataPakExists(locale));
219 EXPECT_EQ(locale, resource_bundle->LoadLocaleResources(locale));
222 TEST_F(ResourceBundleTest, DelegateGetImageNamed) {
223 MockResourceBundleDelegate delegate;
224 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
226 gfx::Image empty_image = resource_bundle->GetEmptyImage();
227 int resource_id = 5;
229 EXPECT_CALL(delegate, GetImageNamed(resource_id))
230 .Times(1)
231 .WillOnce(Return(empty_image));
233 gfx::Image result = resource_bundle->GetImageNamed(resource_id);
234 EXPECT_EQ(empty_image.ToSkBitmap(), result.ToSkBitmap());
237 TEST_F(ResourceBundleTest, DelegateGetNativeImageNamed) {
238 MockResourceBundleDelegate delegate;
239 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
241 gfx::Image empty_image = resource_bundle->GetEmptyImage();
242 int resource_id = 5;
244 // Some platforms delegate GetNativeImageNamed calls to GetImageNamed.
245 EXPECT_CALL(delegate, GetImageNamed(resource_id))
246 .Times(Between(0, 1))
247 .WillOnce(Return(empty_image));
248 EXPECT_CALL(delegate,
249 GetNativeImageNamed(resource_id, ui::ResourceBundle::RTL_DISABLED))
250 .Times(Between(0, 1))
251 .WillOnce(Return(empty_image));
253 gfx::Image result = resource_bundle->GetNativeImageNamed(resource_id);
254 EXPECT_EQ(empty_image.ToSkBitmap(), result.ToSkBitmap());
257 TEST_F(ResourceBundleTest, DelegateLoadDataResourceBytes) {
258 MockResourceBundleDelegate delegate;
259 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
261 // Create the data resource for testing purposes.
262 unsigned char data[] = "My test data";
263 scoped_refptr<base::RefCountedStaticMemory> static_memory(
264 new base::RefCountedStaticMemory(data, sizeof(data)));
266 int resource_id = 5;
267 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_NONE;
269 EXPECT_CALL(delegate, LoadDataResourceBytes(resource_id, scale_factor))
270 .Times(1).WillOnce(Return(static_memory.get()));
272 scoped_refptr<base::RefCountedStaticMemory> result =
273 resource_bundle->LoadDataResourceBytesForScale(resource_id, scale_factor);
274 EXPECT_EQ(static_memory, result);
277 TEST_F(ResourceBundleTest, DelegateGetRawDataResource) {
278 MockResourceBundleDelegate delegate;
279 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
281 // Create the string piece for testing purposes.
282 char data[] = "My test data";
283 base::StringPiece string_piece(data);
285 int resource_id = 5;
287 EXPECT_CALL(delegate, GetRawDataResourceMock(
288 resource_id, ui::SCALE_FACTOR_NONE))
289 .Times(1)
290 .WillOnce(Return(string_piece));
292 base::StringPiece result = resource_bundle->GetRawDataResource(
293 resource_id);
294 EXPECT_EQ(string_piece.data(), result.data());
297 TEST_F(ResourceBundleTest, DelegateGetLocalizedString) {
298 MockResourceBundleDelegate delegate;
299 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
301 base::string16 data = base::ASCIIToUTF16("My test data");
302 int resource_id = 5;
304 EXPECT_CALL(delegate, GetLocalizedStringMock(resource_id))
305 .Times(1)
306 .WillOnce(Return(data));
308 base::string16 result = resource_bundle->GetLocalizedString(resource_id);
309 EXPECT_EQ(data, result);
312 TEST_F(ResourceBundleTest, OverrideStringResource) {
313 ResourceBundle* resource_bundle = CreateResourceBundle(NULL);
315 base::string16 data = base::ASCIIToUTF16("My test data");
316 int resource_id = 5;
318 base::string16 result = resource_bundle->GetLocalizedString(resource_id);
319 EXPECT_EQ(base::string16(), result);
321 resource_bundle->OverrideLocaleStringResource(resource_id, data);
323 result = resource_bundle->GetLocalizedString(resource_id);
324 EXPECT_EQ(data, result);
327 TEST_F(ResourceBundleTest, DelegateGetLocalizedStringWithOverride) {
328 MockResourceBundleDelegate delegate;
329 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
331 base::string16 delegate_data = base::ASCIIToUTF16("My delegate data");
332 int resource_id = 5;
334 EXPECT_CALL(delegate, GetLocalizedStringMock(resource_id)).Times(1).WillOnce(
335 Return(delegate_data));
337 base::string16 override_data = base::ASCIIToUTF16("My override data");
339 base::string16 result = resource_bundle->GetLocalizedString(resource_id);
340 EXPECT_EQ(delegate_data, result);
343 #if (defined(USE_OZONE) && !defined(USE_PANGO)) || defined(OS_ANDROID)
344 #define MAYBE_DelegateGetFontList DISABLED_DelegateGetFontList
345 #else
346 #define MAYBE_DelegateGetFontList DelegateGetFontList
347 #endif
349 TEST_F(ResourceBundleTest, MAYBE_DelegateGetFontList) {
350 MockResourceBundleDelegate delegate;
351 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
353 // Should be called once for each font type. When we return NULL the default
354 // font will be created.
355 gfx::Font* test_font = NULL;
356 EXPECT_CALL(delegate, GetFontMock(_))
357 .Times(8)
358 .WillRepeatedly(Return(test_font));
360 const gfx::FontList* font_list =
361 &resource_bundle->GetFontList(ui::ResourceBundle::BaseFont);
362 EXPECT_TRUE(font_list);
364 const gfx::Font* font =
365 &resource_bundle->GetFont(ui::ResourceBundle::BaseFont);
366 EXPECT_TRUE(font);
369 #if defined(OS_CHROMEOS) && defined(USE_PANGO)
370 TEST_F(ResourceBundleTest, FontListReload) {
371 MockResourceBundleDelegate delegate;
372 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
374 // Should be called once for each font type. When we return NULL the default
375 // font will be created.
376 gfx::Font* test_font = nullptr;
377 EXPECT_CALL(delegate, GetFontMock(_))
378 .Times(16)
379 .WillRepeatedly(Return(test_font));
381 EXPECT_CALL(delegate, GetLocalizedStringMock(IDS_UI_FONT_FAMILY_CROS))
382 .WillOnce(Return(base::UTF8ToUTF16("test font, 12px")));
383 resource_bundle->ReloadFonts();
384 // Don't test the font name; it'll get mapped to something else by Fontconfig.
385 EXPECT_EQ(12, gfx::FontList().GetPrimaryFont().GetFontSize());
386 EXPECT_EQ(gfx::Font::NORMAL, gfx::FontList().GetPrimaryFont().GetStyle());
388 EXPECT_CALL(delegate, GetLocalizedStringMock(IDS_UI_FONT_FAMILY_CROS))
389 .WillOnce(Return(base::UTF8ToUTF16("test font 2, Bold 10px")));
390 resource_bundle->ReloadFonts();
391 EXPECT_EQ(10, gfx::FontList().GetPrimaryFont().GetFontSize());
392 EXPECT_EQ(gfx::Font::BOLD, gfx::FontList().GetPrimaryFont().GetStyle());
394 #endif
396 TEST_F(ResourceBundleTest, LocaleDataPakExists) {
397 ResourceBundle* resource_bundle = CreateResourceBundle(NULL);
399 // Check that ResourceBundle::LocaleDataPakExists returns the correct results.
400 EXPECT_TRUE(resource_bundle->LocaleDataPakExists("en-US"));
401 EXPECT_FALSE(resource_bundle->LocaleDataPakExists("not_a_real_locale"));
404 class ResourceBundleImageTest : public ResourceBundleTest {
405 public:
406 ResourceBundleImageTest() {}
408 ~ResourceBundleImageTest() override {}
410 void SetUp() override {
411 // Create a temporary directory to write test resource bundles to.
412 ASSERT_TRUE(dir_.CreateUniqueTempDir());
415 // Returns resource bundle which uses an empty data pak for locale data.
416 ui::ResourceBundle* CreateResourceBundleWithEmptyLocalePak() {
417 // Write an empty data pak for locale data.
418 const base::FilePath& locale_path = dir_path().Append(
419 FILE_PATH_LITERAL("locale.pak"));
420 EXPECT_EQ(base::WriteFile(locale_path, kEmptyPakContents, kEmptyPakSize),
421 static_cast<int>(kEmptyPakSize));
423 ui::ResourceBundle* resource_bundle = CreateResourceBundle(NULL);
425 // Load the empty locale data pak.
426 resource_bundle->LoadTestResources(base::FilePath(), locale_path);
427 return resource_bundle;
430 // Returns the path of temporary directory to write test data packs into.
431 const base::FilePath& dir_path() { return dir_.path(); }
433 private:
434 scoped_ptr<DataPack> locale_pack_;
435 base::ScopedTempDir dir_;
437 DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageTest);
440 // Verify that we don't crash when trying to load a resource that is not found.
441 // In some cases, we fail to mmap resources.pak, but try to keep going anyway.
442 TEST_F(ResourceBundleImageTest, LoadDataResourceBytes) {
443 base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak"));
445 // Dump contents into the pak files.
446 ASSERT_EQ(base::WriteFile(data_path, kEmptyPakContents,
447 kEmptyPakSize), static_cast<int>(kEmptyPakSize));
449 // Create a resource bundle from the file.
450 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
451 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
453 const int kUnfoundResourceId = 10000;
454 EXPECT_EQ(NULL, resource_bundle->LoadDataResourceBytes(
455 kUnfoundResourceId));
457 // Give a .pak file that doesn't exist so we will fail to load it.
458 resource_bundle->AddDataPackFromPath(
459 base::FilePath(FILE_PATH_LITERAL("non-existant-file.pak")),
460 ui::SCALE_FACTOR_NONE);
461 EXPECT_EQ(NULL, resource_bundle->LoadDataResourceBytes(
462 kUnfoundResourceId));
465 TEST_F(ResourceBundleImageTest, GetRawDataResource) {
466 base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak"));
467 base::FilePath data_2x_path =
468 dir_path().Append(FILE_PATH_LITERAL("sample_2x.pak"));
470 // Dump contents into the pak files.
471 ASSERT_EQ(base::WriteFile(data_path, kSamplePakContents,
472 kSamplePakSize), static_cast<int>(kSamplePakSize));
473 ASSERT_EQ(base::WriteFile(data_2x_path, kSamplePakContents2x,
474 kSamplePakSize2x), static_cast<int>(kSamplePakSize2x));
476 // Load the regular and 2x pak files.
477 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
478 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
479 resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);
481 // Resource ID 4 exists in both 1x and 2x paks, so we expect a different
482 // result when requesting the 2x scale.
483 EXPECT_EQ("this is id 4", resource_bundle->GetRawDataResourceForScale(4,
484 SCALE_FACTOR_100P));
485 EXPECT_EQ("this is id 4 2x", resource_bundle->GetRawDataResourceForScale(4,
486 SCALE_FACTOR_200P));
488 // Resource ID 6 only exists in the 1x pak so we expect the same resource
489 // for both scale factor requests.
490 EXPECT_EQ("this is id 6", resource_bundle->GetRawDataResourceForScale(6,
491 SCALE_FACTOR_100P));
492 EXPECT_EQ("this is id 6", resource_bundle->GetRawDataResourceForScale(6,
493 SCALE_FACTOR_200P));
496 // Test requesting image reps at various scale factors from the image returned
497 // via ResourceBundle::GetImageNamed().
498 TEST_F(ResourceBundleImageTest, GetImageNamed) {
499 #if defined(OS_WIN)
500 gfx::InitDeviceScaleFactor(2.0);
501 #endif
502 std::vector<ScaleFactor> supported_factors;
503 supported_factors.push_back(SCALE_FACTOR_100P);
504 supported_factors.push_back(SCALE_FACTOR_200P);
505 test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
506 base::FilePath data_1x_path = dir_path().AppendASCII("sample_1x.pak");
507 base::FilePath data_2x_path = dir_path().AppendASCII("sample_2x.pak");
509 // Create the pak files.
510 CreateDataPackWithSingleBitmap(data_1x_path, 10, base::StringPiece());
511 CreateDataPackWithSingleBitmap(data_2x_path, 20, base::StringPiece());
513 // Load the regular and 2x pak files.
514 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
515 resource_bundle->AddDataPackFromPath(data_1x_path, SCALE_FACTOR_100P);
516 resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);
518 EXPECT_EQ(SCALE_FACTOR_200P, resource_bundle->GetMaxScaleFactor());
520 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
522 #if defined(OS_CHROMEOS) || defined(OS_WIN)
523 // ChromeOS/Windows load highest scale factor first.
524 EXPECT_EQ(ui::SCALE_FACTOR_200P,
525 GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
526 #else
527 EXPECT_EQ(ui::SCALE_FACTOR_100P,
528 GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
529 #endif
531 // Resource ID 3 exists in both 1x and 2x paks. Image reps should be
532 // available for both scale factors in |image_skia|.
533 gfx::ImageSkiaRep image_rep =
534 image_skia->GetRepresentation(
535 GetScaleForScaleFactor(ui::SCALE_FACTOR_100P));
536 EXPECT_EQ(ui::SCALE_FACTOR_100P, GetSupportedScaleFactor(image_rep.scale()));
537 image_rep =
538 image_skia->GetRepresentation(
539 GetScaleForScaleFactor(ui::SCALE_FACTOR_200P));
540 EXPECT_EQ(ui::SCALE_FACTOR_200P, GetSupportedScaleFactor(image_rep.scale()));
542 // The 1.4x pack was not loaded. Requesting the 1.4x resource should return
543 // either the 1x or the 2x resource.
544 image_rep = image_skia->GetRepresentation(
545 ui::GetScaleForScaleFactor(ui::SCALE_FACTOR_140P));
546 ui::ScaleFactor scale_factor = GetSupportedScaleFactor(image_rep.scale());
547 EXPECT_TRUE(scale_factor == ui::SCALE_FACTOR_100P ||
548 scale_factor == ui::SCALE_FACTOR_200P);
550 // ImageSkia scales image if the one for the requested scale factor is not
551 // available.
552 EXPECT_EQ(1.4f, image_skia->GetRepresentation(1.4f).scale());
555 // Test that GetImageNamed() behaves properly for images which GRIT has
556 // annotated as having fallen back to 1x.
557 TEST_F(ResourceBundleImageTest, GetImageNamedFallback1x) {
558 std::vector<ScaleFactor> supported_factors;
559 supported_factors.push_back(SCALE_FACTOR_100P);
560 supported_factors.push_back(SCALE_FACTOR_200P);
561 test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
562 base::FilePath data_path = dir_path().AppendASCII("sample.pak");
563 base::FilePath data_2x_path = dir_path().AppendASCII("sample_2x.pak");
565 // Create the pak files.
566 CreateDataPackWithSingleBitmap(data_path, 10, base::StringPiece());
567 // 2x data pack bitmap has custom chunk to indicate that the 2x bitmap is not
568 // available and that GRIT fell back to 1x.
569 CreateDataPackWithSingleBitmap(data_2x_path, 10, base::StringPiece(
570 reinterpret_cast<const char*>(kPngScaleChunk),
571 arraysize(kPngScaleChunk)));
573 // Load the regular and 2x pak files.
574 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
575 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
576 resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);
578 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
580 // The image rep for 2x should be available. It should be resized to the
581 // proper 2x size.
582 gfx::ImageSkiaRep image_rep =
583 image_skia->GetRepresentation(GetScaleForScaleFactor(
584 ui::SCALE_FACTOR_200P));
585 EXPECT_EQ(ui::SCALE_FACTOR_200P, GetSupportedScaleFactor(image_rep.scale()));
586 EXPECT_EQ(20, image_rep.pixel_width());
587 EXPECT_EQ(20, image_rep.pixel_height());
590 #if defined(OS_WIN)
591 // Tests GetImageNamed() behaves properly when the size of a scaled image
592 // requires rounding as a result of using a non-integer scale factor.
593 // Scale factors of 140 and 1805 are Windows specific.
594 TEST_F(ResourceBundleImageTest, GetImageNamedFallback1xRounding) {
595 std::vector<ScaleFactor> supported_factors;
596 supported_factors.push_back(SCALE_FACTOR_100P);
597 supported_factors.push_back(SCALE_FACTOR_140P);
598 supported_factors.push_back(SCALE_FACTOR_180P);
599 test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
601 base::FilePath data_path = dir_path().AppendASCII("sample.pak");
602 base::FilePath data_140P_path = dir_path().AppendASCII("sample_140P.pak");
603 base::FilePath data_180P_path = dir_path().AppendASCII("sample_180P.pak");
605 CreateDataPackWithSingleBitmap(data_path, 8, base::StringPiece());
606 // Mark 140% and 180% images as requiring 1x fallback.
607 CreateDataPackWithSingleBitmap(data_140P_path, 8, base::StringPiece(
608 reinterpret_cast<const char*>(kPngScaleChunk),
609 arraysize(kPngScaleChunk)));
610 CreateDataPackWithSingleBitmap(data_180P_path, 8, base::StringPiece(
611 reinterpret_cast<const char*>(kPngScaleChunk),
612 arraysize(kPngScaleChunk)));
614 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
615 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
616 resource_bundle->AddDataPackFromPath(data_140P_path, SCALE_FACTOR_140P);
617 resource_bundle->AddDataPackFromPath(data_180P_path, SCALE_FACTOR_180P);
619 // Non-integer dimensions should be rounded up.
620 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
621 gfx::ImageSkiaRep image_rep =
622 image_skia->GetRepresentation(
623 GetScaleForScaleFactor(ui::SCALE_FACTOR_140P));
624 EXPECT_EQ(12, image_rep.pixel_width());
625 image_rep = image_skia->GetRepresentation(
626 GetScaleForScaleFactor(ui::SCALE_FACTOR_180P));
627 EXPECT_EQ(15, image_rep.pixel_width());
629 #endif
631 #if defined(OS_IOS)
632 // Fails on devices that have non-100P scaling. See crbug.com/298406
633 #define MAYBE_FallbackToNone DISABLED_FallbackToNone
634 #else
635 #define MAYBE_FallbackToNone FallbackToNone
636 #endif
637 TEST_F(ResourceBundleImageTest, MAYBE_FallbackToNone) {
638 base::FilePath data_default_path = dir_path().AppendASCII("sample.pak");
640 // Create the pak files.
641 CreateDataPackWithSingleBitmap(data_default_path, 10, base::StringPiece());
643 // Load the regular pak files only.
644 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
645 resource_bundle->AddDataPackFromPath(data_default_path, SCALE_FACTOR_NONE);
647 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
648 EXPECT_EQ(1u, image_skia->image_reps().size());
649 EXPECT_TRUE(image_skia->image_reps()[0].unscaled());
650 EXPECT_EQ(ui::SCALE_FACTOR_100P,
651 GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
654 } // namespace ui