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/file_util.h"
10 #include "base/files/file_path.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/path_service.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/base/layout.h"
20 #include "ui/base/resource/data_pack.h"
21 #include "ui/gfx/codec/png_codec.h"
22 #include "ui/gfx/image/image_skia.h"
23 #include "ui/resources/grit/ui_resources.h"
26 #include "ui/gfx/win/dpi.h"
30 using ::testing::Between
;
31 using ::testing::Property
;
32 using ::testing::Return
;
33 using ::testing::ReturnArg
;
37 extern const char kSamplePakContents
[];
38 extern const size_t kSamplePakSize
;
39 extern const char kSamplePakContents2x
[];
40 extern const size_t kSamplePakSize2x
;
41 extern const char kEmptyPakContents
[];
42 extern const size_t kEmptyPakSize
;
46 const unsigned char kPngMagic
[8] = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 };
47 const size_t kPngChunkMetadataSize
= 12;
48 const unsigned char kPngIHDRChunkType
[4] = { 'I', 'H', 'D', 'R' };
50 // Custom chunk that GRIT adds to PNG to indicate that it could not find a
51 // bitmap at the requested scale factor and fell back to 1x.
52 const unsigned char kPngScaleChunk
[12] = { 0x00, 0x00, 0x00, 0x00,
54 0xc1, 0x30, 0x60, 0x4d };
56 // Mock for the ResourceBundle::Delegate class.
57 class MockResourceBundleDelegate
: public ui::ResourceBundle::Delegate
{
59 MockResourceBundleDelegate() {
61 virtual ~MockResourceBundleDelegate() {
64 MOCK_METHOD2(GetPathForResourcePack
, base::FilePath(
65 const base::FilePath
& pack_path
, ui::ScaleFactor scale_factor
));
66 MOCK_METHOD2(GetPathForLocalePack
, base::FilePath(
67 const base::FilePath
& pack_path
, const std::string
& locale
));
68 MOCK_METHOD1(GetImageNamed
, gfx::Image(int resource_id
));
69 MOCK_METHOD2(GetNativeImageNamed
,
70 gfx::Image(int resource_id
,
71 ui::ResourceBundle::ImageRTL rtl
));
72 MOCK_METHOD2(LoadDataResourceBytes
,
73 base::RefCountedStaticMemory
*(int resource_id
,
74 ui::ScaleFactor scale_factor
));
75 MOCK_METHOD2(GetRawDataResourceMock
, base::StringPiece(
77 ui::ScaleFactor scale_factor
));
78 virtual bool GetRawDataResource(int resource_id
,
79 ui::ScaleFactor scale_factor
,
80 base::StringPiece
* value
) OVERRIDE
{
81 *value
= GetRawDataResourceMock(resource_id
, scale_factor
);
84 MOCK_METHOD1(GetLocalizedStringMock
, base::string16(int message_id
));
85 virtual bool GetLocalizedString(int message_id
,
86 base::string16
* value
) OVERRIDE
{
87 *value
= GetLocalizedStringMock(message_id
);
90 MOCK_METHOD1(GetFontMock
,
91 gfx::Font
*(ui::ResourceBundle::FontStyle style
));
92 virtual scoped_ptr
<gfx::Font
> GetFont(
93 ui::ResourceBundle::FontStyle style
) OVERRIDE
{
94 return scoped_ptr
<gfx::Font
>(GetFontMock(style
));
98 // Returns |bitmap_data| with |custom_chunk| inserted after the IHDR chunk.
99 void AddCustomChunk(const base::StringPiece
& custom_chunk
,
100 std::vector
<unsigned char>* bitmap_data
) {
101 EXPECT_LT(arraysize(kPngMagic
) + kPngChunkMetadataSize
, bitmap_data
->size());
102 EXPECT_TRUE(std::equal(
103 bitmap_data
->begin(),
104 bitmap_data
->begin() + arraysize(kPngMagic
),
106 std::vector
<unsigned char>::iterator ihdr_start
=
107 bitmap_data
->begin() + arraysize(kPngMagic
);
108 char ihdr_length_data
[sizeof(uint32
)];
109 for (size_t i
= 0; i
< sizeof(uint32
); ++i
)
110 ihdr_length_data
[i
] = *(ihdr_start
+ i
);
111 uint32 ihdr_chunk_length
= 0;
112 base::ReadBigEndian(reinterpret_cast<char*>(ihdr_length_data
),
114 EXPECT_TRUE(std::equal(
115 ihdr_start
+ sizeof(uint32
),
116 ihdr_start
+ sizeof(uint32
) + sizeof(kPngIHDRChunkType
),
119 bitmap_data
->insert(ihdr_start
+ kPngChunkMetadataSize
+ ihdr_chunk_length
,
120 custom_chunk
.begin(), custom_chunk
.end());
123 // Creates datapack at |path| with a single bitmap at resource ID 3
124 // which is |edge_size|x|edge_size| pixels.
125 // If |custom_chunk| is non empty, adds it after the IHDR chunk
126 // in the encoded bitmap data.
127 void CreateDataPackWithSingleBitmap(const base::FilePath
& path
,
129 const base::StringPiece
& custom_chunk
) {
131 bitmap
.allocN32Pixels(edge_size
, edge_size
);
132 bitmap
.eraseColor(SK_ColorWHITE
);
133 std::vector
<unsigned char> bitmap_data
;
134 EXPECT_TRUE(gfx::PNGCodec::EncodeBGRASkBitmap(bitmap
, false, &bitmap_data
));
136 if (custom_chunk
.size() > 0)
137 AddCustomChunk(custom_chunk
, &bitmap_data
);
139 std::map
<uint16
, base::StringPiece
> resources
;
140 resources
[3u] = base::StringPiece(
141 reinterpret_cast<const char*>(&bitmap_data
[0]), bitmap_data
.size());
142 DataPack::WritePack(path
, resources
, ui::DataPack::BINARY
);
147 class ResourceBundleTest
: public testing::Test
{
149 ResourceBundleTest() : resource_bundle_(NULL
) {
152 virtual ~ResourceBundleTest() {
155 // Overridden from testing::Test:
156 virtual void TearDown() OVERRIDE
{
157 delete resource_bundle_
;
160 // Returns new ResoureBundle with the specified |delegate|. The
161 // ResourceBundleTest class manages the lifetime of the returned
163 ResourceBundle
* CreateResourceBundle(ResourceBundle::Delegate
* delegate
) {
164 DCHECK(!resource_bundle_
);
166 resource_bundle_
= new ResourceBundle(delegate
);
167 return resource_bundle_
;
171 ResourceBundle
* resource_bundle_
;
174 DISALLOW_COPY_AND_ASSIGN(ResourceBundleTest
);
177 TEST_F(ResourceBundleTest
, DelegateGetPathForResourcePack
) {
178 MockResourceBundleDelegate delegate
;
179 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
181 base::FilePath
pack_path(FILE_PATH_LITERAL("/path/to/test_path.pak"));
182 ui::ScaleFactor pack_scale_factor
= ui::SCALE_FACTOR_200P
;
184 EXPECT_CALL(delegate
,
185 GetPathForResourcePack(
186 Property(&base::FilePath::value
, pack_path
.value()),
189 .WillOnce(Return(pack_path
));
191 resource_bundle
->AddDataPackFromPath(pack_path
, pack_scale_factor
);
194 #if defined(OS_LINUX)
195 // Fails consistently on Linux: crbug.com/161902
196 #define MAYBE_DelegateGetPathForLocalePack DISABLED_DelegateGetPathForLocalePack
198 #define MAYBE_DelegateGetPathForLocalePack DelegateGetPathForLocalePack
200 TEST_F(ResourceBundleTest
, MAYBE_DelegateGetPathForLocalePack
) {
201 MockResourceBundleDelegate delegate
;
202 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
204 std::string locale
= "en-US";
207 EXPECT_CALL(delegate
, GetPathForLocalePack(_
, locale
))
209 .WillRepeatedly(Return(base::FilePath()))
210 .RetiresOnSaturation();
212 EXPECT_FALSE(resource_bundle
->LocaleDataPakExists(locale
));
213 EXPECT_EQ("", resource_bundle
->LoadLocaleResources(locale
));
215 // Allow the load to proceed.
216 EXPECT_CALL(delegate
, GetPathForLocalePack(_
, locale
))
218 .WillRepeatedly(ReturnArg
<0>());
220 EXPECT_TRUE(resource_bundle
->LocaleDataPakExists(locale
));
221 EXPECT_EQ(locale
, resource_bundle
->LoadLocaleResources(locale
));
224 TEST_F(ResourceBundleTest
, DelegateGetImageNamed
) {
225 MockResourceBundleDelegate delegate
;
226 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
228 gfx::Image empty_image
= resource_bundle
->GetEmptyImage();
231 EXPECT_CALL(delegate
, GetImageNamed(resource_id
))
233 .WillOnce(Return(empty_image
));
235 gfx::Image result
= resource_bundle
->GetImageNamed(resource_id
);
236 EXPECT_EQ(empty_image
.ToSkBitmap(), result
.ToSkBitmap());
239 TEST_F(ResourceBundleTest
, DelegateGetNativeImageNamed
) {
240 MockResourceBundleDelegate delegate
;
241 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
243 gfx::Image empty_image
= resource_bundle
->GetEmptyImage();
246 // Some platforms delegate GetNativeImageNamed calls to GetImageNamed.
247 EXPECT_CALL(delegate
, GetImageNamed(resource_id
))
248 .Times(Between(0, 1))
249 .WillOnce(Return(empty_image
));
250 EXPECT_CALL(delegate
,
251 GetNativeImageNamed(resource_id
, ui::ResourceBundle::RTL_DISABLED
))
252 .Times(Between(0, 1))
253 .WillOnce(Return(empty_image
));
255 gfx::Image result
= resource_bundle
->GetNativeImageNamed(resource_id
);
256 EXPECT_EQ(empty_image
.ToSkBitmap(), result
.ToSkBitmap());
259 TEST_F(ResourceBundleTest
, DelegateLoadDataResourceBytes
) {
260 MockResourceBundleDelegate delegate
;
261 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
263 // Create the data resource for testing purposes.
264 unsigned char data
[] = "My test data";
265 scoped_refptr
<base::RefCountedStaticMemory
> static_memory(
266 new base::RefCountedStaticMemory(data
, sizeof(data
)));
269 ui::ScaleFactor scale_factor
= ui::SCALE_FACTOR_NONE
;
271 EXPECT_CALL(delegate
, LoadDataResourceBytes(resource_id
, scale_factor
))
272 .Times(1).WillOnce(Return(static_memory
.get()));
274 scoped_refptr
<base::RefCountedStaticMemory
> result
=
275 resource_bundle
->LoadDataResourceBytesForScale(resource_id
, scale_factor
);
276 EXPECT_EQ(static_memory
, result
);
279 TEST_F(ResourceBundleTest
, DelegateGetRawDataResource
) {
280 MockResourceBundleDelegate delegate
;
281 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
283 // Create the string piece for testing purposes.
284 char data
[] = "My test data";
285 base::StringPiece
string_piece(data
);
289 EXPECT_CALL(delegate
, GetRawDataResourceMock(
290 resource_id
, ui::SCALE_FACTOR_NONE
))
292 .WillOnce(Return(string_piece
));
294 base::StringPiece result
= resource_bundle
->GetRawDataResource(
296 EXPECT_EQ(string_piece
.data(), result
.data());
299 TEST_F(ResourceBundleTest
, DelegateGetLocalizedString
) {
300 MockResourceBundleDelegate delegate
;
301 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
303 base::string16 data
= base::ASCIIToUTF16("My test data");
306 EXPECT_CALL(delegate
, GetLocalizedStringMock(resource_id
))
308 .WillOnce(Return(data
));
310 base::string16 result
= resource_bundle
->GetLocalizedString(resource_id
);
311 EXPECT_EQ(data
, result
);
314 TEST_F(ResourceBundleTest
, OverrideStringResource
) {
315 ResourceBundle
* resource_bundle
= CreateResourceBundle(NULL
);
317 base::string16 data
= base::ASCIIToUTF16("My test data");
320 base::string16 result
= resource_bundle
->GetLocalizedString(resource_id
);
321 EXPECT_EQ(base::string16(), result
);
323 resource_bundle
->OverrideLocaleStringResource(resource_id
, data
);
325 result
= resource_bundle
->GetLocalizedString(resource_id
);
326 EXPECT_EQ(data
, result
);
329 TEST_F(ResourceBundleTest
, DelegateGetLocalizedStringWithOverride
) {
330 MockResourceBundleDelegate delegate
;
331 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
333 base::string16 delegate_data
= base::ASCIIToUTF16("My delegate data");
336 EXPECT_CALL(delegate
, GetLocalizedStringMock(resource_id
)).Times(1).WillOnce(
337 Return(delegate_data
));
339 base::string16 override_data
= base::ASCIIToUTF16("My override data");
341 base::string16 result
= resource_bundle
->GetLocalizedString(resource_id
);
342 EXPECT_EQ(delegate_data
, result
);
345 #if defined(USE_OZONE) && !defined(USE_PANGO)
346 #define MAYBE_DelegateGetFontList DISABLED_DelegateGetFontList
348 #define MAYBE_DelegateGetFontList DelegateGetFontList
351 TEST_F(ResourceBundleTest
, MAYBE_DelegateGetFontList
) {
352 MockResourceBundleDelegate delegate
;
353 ResourceBundle
* resource_bundle
= CreateResourceBundle(&delegate
);
355 // Should be called once for each font type. When we return NULL the default
356 // font will be created.
357 gfx::Font
* test_font
= NULL
;
358 EXPECT_CALL(delegate
, GetFontMock(_
))
360 .WillRepeatedly(Return(test_font
));
362 const gfx::FontList
* font_list
=
363 &resource_bundle
->GetFontList(ui::ResourceBundle::BaseFont
);
364 EXPECT_TRUE(font_list
);
366 const gfx::Font
* font
=
367 &resource_bundle
->GetFont(ui::ResourceBundle::BaseFont
);
371 TEST_F(ResourceBundleTest
, LocaleDataPakExists
) {
372 ResourceBundle
* resource_bundle
= CreateResourceBundle(NULL
);
374 // Check that ResourceBundle::LocaleDataPakExists returns the correct results.
375 EXPECT_TRUE(resource_bundle
->LocaleDataPakExists("en-US"));
376 EXPECT_FALSE(resource_bundle
->LocaleDataPakExists("not_a_real_locale"));
379 class ResourceBundleImageTest
: public ResourceBundleTest
{
381 ResourceBundleImageTest() {}
383 virtual ~ResourceBundleImageTest() {
386 virtual void SetUp() OVERRIDE
{
387 // Create a temporary directory to write test resource bundles to.
388 ASSERT_TRUE(dir_
.CreateUniqueTempDir());
391 // Returns resource bundle which uses an empty data pak for locale data.
392 ui::ResourceBundle
* CreateResourceBundleWithEmptyLocalePak() {
393 // Write an empty data pak for locale data.
394 const base::FilePath
& locale_path
= dir_path().Append(
395 FILE_PATH_LITERAL("locale.pak"));
396 EXPECT_EQ(base::WriteFile(locale_path
, kEmptyPakContents
, kEmptyPakSize
),
397 static_cast<int>(kEmptyPakSize
));
399 ui::ResourceBundle
* resource_bundle
= CreateResourceBundle(NULL
);
401 // Load the empty locale data pak.
402 resource_bundle
->LoadTestResources(base::FilePath(), locale_path
);
403 return resource_bundle
;
406 // Returns the path of temporary directory to write test data packs into.
407 const base::FilePath
& dir_path() { return dir_
.path(); }
410 scoped_ptr
<DataPack
> locale_pack_
;
411 base::ScopedTempDir dir_
;
413 DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageTest
);
416 // Verify that we don't crash when trying to load a resource that is not found.
417 // In some cases, we fail to mmap resources.pak, but try to keep going anyway.
418 TEST_F(ResourceBundleImageTest
, LoadDataResourceBytes
) {
419 base::FilePath data_path
= dir_path().Append(FILE_PATH_LITERAL("sample.pak"));
421 // Dump contents into the pak files.
422 ASSERT_EQ(base::WriteFile(data_path
, kEmptyPakContents
,
423 kEmptyPakSize
), static_cast<int>(kEmptyPakSize
));
425 // Create a resource bundle from the file.
426 ResourceBundle
* resource_bundle
= CreateResourceBundleWithEmptyLocalePak();
427 resource_bundle
->AddDataPackFromPath(data_path
, SCALE_FACTOR_100P
);
429 const int kUnfoundResourceId
= 10000;
430 EXPECT_EQ(NULL
, resource_bundle
->LoadDataResourceBytes(
431 kUnfoundResourceId
));
433 // Give a .pak file that doesn't exist so we will fail to load it.
434 resource_bundle
->AddDataPackFromPath(
435 base::FilePath(FILE_PATH_LITERAL("non-existant-file.pak")),
436 ui::SCALE_FACTOR_NONE
);
437 EXPECT_EQ(NULL
, resource_bundle
->LoadDataResourceBytes(
438 kUnfoundResourceId
));
441 TEST_F(ResourceBundleImageTest
, GetRawDataResource
) {
442 base::FilePath data_path
= dir_path().Append(FILE_PATH_LITERAL("sample.pak"));
443 base::FilePath data_2x_path
=
444 dir_path().Append(FILE_PATH_LITERAL("sample_2x.pak"));
446 // Dump contents into the pak files.
447 ASSERT_EQ(base::WriteFile(data_path
, kSamplePakContents
,
448 kSamplePakSize
), static_cast<int>(kSamplePakSize
));
449 ASSERT_EQ(base::WriteFile(data_2x_path
, kSamplePakContents2x
,
450 kSamplePakSize2x
), static_cast<int>(kSamplePakSize2x
));
452 // Load the regular and 2x pak files.
453 ResourceBundle
* resource_bundle
= CreateResourceBundleWithEmptyLocalePak();
454 resource_bundle
->AddDataPackFromPath(data_path
, SCALE_FACTOR_100P
);
455 resource_bundle
->AddDataPackFromPath(data_2x_path
, SCALE_FACTOR_200P
);
457 // Resource ID 4 exists in both 1x and 2x paks, so we expect a different
458 // result when requesting the 2x scale.
459 EXPECT_EQ("this is id 4", resource_bundle
->GetRawDataResourceForScale(4,
461 EXPECT_EQ("this is id 4 2x", resource_bundle
->GetRawDataResourceForScale(4,
464 // Resource ID 6 only exists in the 1x pak so we expect the same resource
465 // for both scale factor requests.
466 EXPECT_EQ("this is id 6", resource_bundle
->GetRawDataResourceForScale(6,
468 EXPECT_EQ("this is id 6", resource_bundle
->GetRawDataResourceForScale(6,
472 // Test requesting image reps at various scale factors from the image returned
473 // via ResourceBundle::GetImageNamed().
474 TEST_F(ResourceBundleImageTest
, GetImageNamed
) {
476 gfx::ForceHighDPISupportForTesting(2.0);
478 std::vector
<ScaleFactor
> supported_factors
;
479 supported_factors
.push_back(SCALE_FACTOR_100P
);
480 supported_factors
.push_back(SCALE_FACTOR_200P
);
481 test::ScopedSetSupportedScaleFactors
scoped_supported(supported_factors
);
482 base::FilePath data_1x_path
= dir_path().AppendASCII("sample_1x.pak");
483 base::FilePath data_2x_path
= dir_path().AppendASCII("sample_2x.pak");
485 // Create the pak files.
486 CreateDataPackWithSingleBitmap(data_1x_path
, 10, base::StringPiece());
487 CreateDataPackWithSingleBitmap(data_2x_path
, 20, base::StringPiece());
489 // Load the regular and 2x pak files.
490 ResourceBundle
* resource_bundle
= CreateResourceBundleWithEmptyLocalePak();
491 resource_bundle
->AddDataPackFromPath(data_1x_path
, SCALE_FACTOR_100P
);
492 resource_bundle
->AddDataPackFromPath(data_2x_path
, SCALE_FACTOR_200P
);
494 EXPECT_EQ(SCALE_FACTOR_200P
, resource_bundle
->GetMaxScaleFactor());
496 gfx::ImageSkia
* image_skia
= resource_bundle
->GetImageSkiaNamed(3);
498 #if defined(OS_CHROMEOS) || defined(OS_WIN)
499 // ChromeOS/Windows load highest scale factor first.
500 EXPECT_EQ(ui::SCALE_FACTOR_200P
,
501 GetSupportedScaleFactor(image_skia
->image_reps()[0].scale()));
503 EXPECT_EQ(ui::SCALE_FACTOR_100P
,
504 GetSupportedScaleFactor(image_skia
->image_reps()[0].scale()));
507 // Resource ID 3 exists in both 1x and 2x paks. Image reps should be
508 // available for both scale factors in |image_skia|.
509 gfx::ImageSkiaRep image_rep
=
510 image_skia
->GetRepresentation(
511 GetScaleForScaleFactor(ui::SCALE_FACTOR_100P
));
512 EXPECT_EQ(ui::SCALE_FACTOR_100P
, GetSupportedScaleFactor(image_rep
.scale()));
514 image_skia
->GetRepresentation(
515 GetScaleForScaleFactor(ui::SCALE_FACTOR_200P
));
516 EXPECT_EQ(ui::SCALE_FACTOR_200P
, GetSupportedScaleFactor(image_rep
.scale()));
518 // The 1.4x pack was not loaded. Requesting the 1.4x resource should return
519 // either the 1x or the 2x resource.
520 image_rep
= image_skia
->GetRepresentation(
521 ui::GetScaleForScaleFactor(ui::SCALE_FACTOR_140P
));
522 ui::ScaleFactor scale_factor
= GetSupportedScaleFactor(image_rep
.scale());
523 EXPECT_TRUE(scale_factor
== ui::SCALE_FACTOR_100P
||
524 scale_factor
== ui::SCALE_FACTOR_200P
);
526 // ImageSkia scales image if the one for the requested scale factor is not
528 EXPECT_EQ(1.4f
, image_skia
->GetRepresentation(1.4f
).scale());
531 // Test that GetImageNamed() behaves properly for images which GRIT has
532 // annotated as having fallen back to 1x.
533 TEST_F(ResourceBundleImageTest
, GetImageNamedFallback1x
) {
534 std::vector
<ScaleFactor
> supported_factors
;
535 supported_factors
.push_back(SCALE_FACTOR_100P
);
536 supported_factors
.push_back(SCALE_FACTOR_200P
);
537 test::ScopedSetSupportedScaleFactors
scoped_supported(supported_factors
);
538 base::FilePath data_path
= dir_path().AppendASCII("sample.pak");
539 base::FilePath data_2x_path
= dir_path().AppendASCII("sample_2x.pak");
541 // Create the pak files.
542 CreateDataPackWithSingleBitmap(data_path
, 10, base::StringPiece());
543 // 2x data pack bitmap has custom chunk to indicate that the 2x bitmap is not
544 // available and that GRIT fell back to 1x.
545 CreateDataPackWithSingleBitmap(data_2x_path
, 10, base::StringPiece(
546 reinterpret_cast<const char*>(kPngScaleChunk
),
547 arraysize(kPngScaleChunk
)));
549 // Load the regular and 2x pak files.
550 ResourceBundle
* resource_bundle
= CreateResourceBundleWithEmptyLocalePak();
551 resource_bundle
->AddDataPackFromPath(data_path
, SCALE_FACTOR_100P
);
552 resource_bundle
->AddDataPackFromPath(data_2x_path
, SCALE_FACTOR_200P
);
554 gfx::ImageSkia
* image_skia
= resource_bundle
->GetImageSkiaNamed(3);
556 // The image rep for 2x should be available. It should be resized to the
558 gfx::ImageSkiaRep image_rep
=
559 image_skia
->GetRepresentation(GetScaleForScaleFactor(
560 ui::SCALE_FACTOR_200P
));
561 EXPECT_EQ(ui::SCALE_FACTOR_200P
, GetSupportedScaleFactor(image_rep
.scale()));
562 EXPECT_EQ(20, image_rep
.pixel_width());
563 EXPECT_EQ(20, image_rep
.pixel_height());
567 // Tests GetImageNamed() behaves properly when the size of a scaled image
568 // requires rounding as a result of using a non-integer scale factor.
569 // Scale factors of 140 and 1805 are Windows specific.
570 TEST_F(ResourceBundleImageTest
, GetImageNamedFallback1xRounding
) {
571 std::vector
<ScaleFactor
> supported_factors
;
572 supported_factors
.push_back(SCALE_FACTOR_100P
);
573 supported_factors
.push_back(SCALE_FACTOR_140P
);
574 supported_factors
.push_back(SCALE_FACTOR_180P
);
575 test::ScopedSetSupportedScaleFactors
scoped_supported(supported_factors
);
577 base::FilePath data_path
= dir_path().AppendASCII("sample.pak");
578 base::FilePath data_140P_path
= dir_path().AppendASCII("sample_140P.pak");
579 base::FilePath data_180P_path
= dir_path().AppendASCII("sample_180P.pak");
581 CreateDataPackWithSingleBitmap(data_path
, 8, base::StringPiece());
582 // Mark 140% and 180% images as requiring 1x fallback.
583 CreateDataPackWithSingleBitmap(data_140P_path
, 8, base::StringPiece(
584 reinterpret_cast<const char*>(kPngScaleChunk
),
585 arraysize(kPngScaleChunk
)));
586 CreateDataPackWithSingleBitmap(data_180P_path
, 8, base::StringPiece(
587 reinterpret_cast<const char*>(kPngScaleChunk
),
588 arraysize(kPngScaleChunk
)));
590 ResourceBundle
* resource_bundle
= CreateResourceBundleWithEmptyLocalePak();
591 resource_bundle
->AddDataPackFromPath(data_path
, SCALE_FACTOR_100P
);
592 resource_bundle
->AddDataPackFromPath(data_140P_path
, SCALE_FACTOR_140P
);
593 resource_bundle
->AddDataPackFromPath(data_180P_path
, SCALE_FACTOR_180P
);
595 // Non-integer dimensions should be rounded up.
596 gfx::ImageSkia
* image_skia
= resource_bundle
->GetImageSkiaNamed(3);
597 gfx::ImageSkiaRep image_rep
=
598 image_skia
->GetRepresentation(
599 GetScaleForScaleFactor(ui::SCALE_FACTOR_140P
));
600 EXPECT_EQ(12, image_rep
.pixel_width());
601 image_rep
= image_skia
->GetRepresentation(
602 GetScaleForScaleFactor(ui::SCALE_FACTOR_180P
));
603 EXPECT_EQ(15, image_rep
.pixel_width());
608 // Fails on devices that have non-100P scaling. See crbug.com/298406
609 #define MAYBE_FallbackToNone DISABLED_FallbackToNone
611 #define MAYBE_FallbackToNone FallbackToNone
613 TEST_F(ResourceBundleImageTest
, MAYBE_FallbackToNone
) {
614 base::FilePath data_default_path
= dir_path().AppendASCII("sample.pak");
616 // Create the pak files.
617 CreateDataPackWithSingleBitmap(data_default_path
, 10, base::StringPiece());
619 // Load the regular pak files only.
620 ResourceBundle
* resource_bundle
= CreateResourceBundleWithEmptyLocalePak();
621 resource_bundle
->AddDataPackFromPath(data_default_path
, SCALE_FACTOR_NONE
);
623 gfx::ImageSkia
* image_skia
= resource_bundle
->GetImageSkiaNamed(3);
624 EXPECT_EQ(1u, image_skia
->image_reps().size());
625 EXPECT_TRUE(image_skia
->image_reps()[0].unscaled());
626 EXPECT_EQ(ui::SCALE_FACTOR_100P
,
627 GetSupportedScaleFactor(image_skia
->image_reps()[0].scale()));