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/gfx/image/image_skia.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/threading/simple_thread.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/skia/include/core/SkBitmap.h"
12 #include "ui/gfx/geometry/size.h"
13 #include "ui/gfx/image/image_skia_rep.h"
14 #include "ui/gfx/image/image_skia_source.h"
15 #include "ui/gfx/switches.h"
17 // Duplicated from base/threading/non_thread_safe.h so that we can be
18 // good citizens there and undef the macro.
19 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
20 #define ENABLE_NON_THREAD_SAFE 1
22 #define ENABLE_NON_THREAD_SAFE 0
29 class FixedSource
: public ImageSkiaSource
{
31 explicit FixedSource(const ImageSkiaRep
& image
) : image_(image
) {}
33 ~FixedSource() override
{}
35 ImageSkiaRep
GetImageForScale(float scale
) override
{ return image_
; }
40 DISALLOW_COPY_AND_ASSIGN(FixedSource
);
43 class FixedScaleSource
: public ImageSkiaSource
{
45 explicit FixedScaleSource(const ImageSkiaRep
& image
) : image_(image
) {}
47 ~FixedScaleSource() override
{}
49 ImageSkiaRep
GetImageForScale(float scale
) override
{
50 if (!image_
.unscaled() && image_
.scale() != scale
)
51 return ImageSkiaRep();
58 DISALLOW_COPY_AND_ASSIGN(FixedScaleSource
);
61 class DynamicSource
: public ImageSkiaSource
{
63 explicit DynamicSource(const gfx::Size
& size
)
65 last_requested_scale_(0.0f
) {}
67 ~DynamicSource() override
{}
69 ImageSkiaRep
GetImageForScale(float scale
) override
{
70 last_requested_scale_
= scale
;
71 return gfx::ImageSkiaRep(size_
, scale
);
74 float GetLastRequestedScaleAndReset() {
75 float result
= last_requested_scale_
;
76 last_requested_scale_
= 0.0f
;
82 float last_requested_scale_
;
84 DISALLOW_COPY_AND_ASSIGN(DynamicSource
);
87 class NullSource
: public ImageSkiaSource
{
92 ~NullSource() override
{}
94 ImageSkiaRep
GetImageForScale(float scale
) override
{
95 return gfx::ImageSkiaRep();
99 DISALLOW_COPY_AND_ASSIGN(NullSource
);
105 class TestOnThread
: public base::SimpleThread
{
107 explicit TestOnThread(ImageSkia
* image_skia
)
108 : SimpleThread("image_skia_on_thread"),
109 image_skia_(image_skia
),
114 void Run() override
{
115 can_read_
= image_skia_
->CanRead();
116 can_modify_
= image_skia_
->CanModify();
118 image_skia_
->image_reps();
121 void StartAndJoin() {
126 bool can_read() const { return can_read_
; }
128 bool can_modify() const { return can_modify_
; }
131 ImageSkia
* image_skia_
;
136 DISALLOW_COPY_AND_ASSIGN(TestOnThread
);
141 class ImageSkiaTest
: public testing::Test
{
144 // In the test, we assume that we support 1.0f and 2.0f DSFs.
145 old_scales_
= ImageSkia::GetSupportedScales();
147 // Sets the list of scale factors supported by resource bundle.
148 std::vector
<float> supported_scales
;
149 supported_scales
.push_back(1.0f
);
150 supported_scales
.push_back(2.0f
);
151 ImageSkia::SetSupportedScales(supported_scales
);
153 ~ImageSkiaTest() override
{ ImageSkia::SetSupportedScales(old_scales_
); }
156 std::vector
<float> old_scales_
;
157 DISALLOW_COPY_AND_ASSIGN(ImageSkiaTest
);
160 TEST_F(ImageSkiaTest
, FixedSource
) {
161 ImageSkiaRep
image(Size(100, 200), 0.0f
);
162 ImageSkia
image_skia(new FixedSource(image
), Size(100, 200));
163 EXPECT_EQ(0U, image_skia
.image_reps().size());
165 const ImageSkiaRep
& result_100p
= image_skia
.GetRepresentation(1.0f
);
166 EXPECT_EQ(100, result_100p
.GetWidth());
167 EXPECT_EQ(200, result_100p
.GetHeight());
168 EXPECT_EQ(1.0f
, result_100p
.scale());
169 EXPECT_EQ(1U, image_skia
.image_reps().size());
171 const ImageSkiaRep
& result_200p
= image_skia
.GetRepresentation(2.0f
);
173 EXPECT_EQ(100, result_200p
.GetWidth());
174 EXPECT_EQ(200, result_200p
.GetHeight());
175 EXPECT_EQ(100, result_200p
.pixel_width());
176 EXPECT_EQ(200, result_200p
.pixel_height());
177 EXPECT_EQ(1.0f
, result_200p
.scale());
178 EXPECT_EQ(1U, image_skia
.image_reps().size());
180 const ImageSkiaRep
& result_300p
= image_skia
.GetRepresentation(3.0f
);
182 EXPECT_EQ(100, result_300p
.GetWidth());
183 EXPECT_EQ(200, result_300p
.GetHeight());
184 EXPECT_EQ(100, result_300p
.pixel_width());
185 EXPECT_EQ(200, result_300p
.pixel_height());
186 EXPECT_EQ(1.0f
, result_300p
.scale());
187 EXPECT_EQ(1U, image_skia
.image_reps().size());
189 // Get the representation again and make sure it doesn't
190 // generate new image skia rep.
191 image_skia
.GetRepresentation(1.0f
);
192 image_skia
.GetRepresentation(2.0f
);
193 image_skia
.GetRepresentation(3.0f
);
194 EXPECT_EQ(1U, image_skia
.image_reps().size());
197 TEST_F(ImageSkiaTest
, FixedScaledSource
) {
198 ImageSkiaRep
image(Size(100, 200), 1.0f
);
199 ImageSkia
image_skia(new FixedScaleSource(image
), Size(100, 200));
200 EXPECT_EQ(0U, image_skia
.image_reps().size());
202 const ImageSkiaRep
& result_100p
= image_skia
.GetRepresentation(1.0f
);
203 EXPECT_EQ(100, result_100p
.GetWidth());
204 EXPECT_EQ(200, result_100p
.GetHeight());
205 EXPECT_EQ(1.0f
, result_100p
.scale());
206 EXPECT_EQ(1U, image_skia
.image_reps().size());
208 // 2.0f data doesn't exist, then it falls back to 1.0f and rescale it.
209 const ImageSkiaRep
& result_200p
= image_skia
.GetRepresentation(2.0f
);
211 EXPECT_EQ(100, result_200p
.GetWidth());
212 EXPECT_EQ(200, result_200p
.GetHeight());
213 EXPECT_EQ(200, result_200p
.pixel_width());
214 EXPECT_EQ(400, result_200p
.pixel_height());
215 EXPECT_EQ(2.0f
, result_200p
.scale());
216 EXPECT_EQ(2U, image_skia
.image_reps().size());
218 // Get the representation again and make sure it doesn't
219 // generate new image skia rep.
220 image_skia
.GetRepresentation(1.0f
);
221 image_skia
.GetRepresentation(2.0f
);
222 EXPECT_EQ(2U, image_skia
.image_reps().size());
225 TEST_F(ImageSkiaTest
, FixedUnscaledSource
) {
226 ImageSkiaRep
image(Size(100, 200), 0.0f
);
227 ImageSkia
image_skia(new FixedScaleSource(image
), Size(100, 200));
228 EXPECT_EQ(0U, image_skia
.image_reps().size());
230 const ImageSkiaRep
& result_100p
= image_skia
.GetRepresentation(1.0f
);
231 EXPECT_EQ(100, result_100p
.pixel_width());
232 EXPECT_EQ(200, result_100p
.pixel_height());
233 EXPECT_TRUE(result_100p
.unscaled());
234 EXPECT_EQ(1U, image_skia
.image_reps().size());
236 // 2.0f data doesn't exist, but unscaled ImageSkiaRep shouldn't be rescaled.
237 const ImageSkiaRep
& result_200p
= image_skia
.GetRepresentation(2.0f
);
239 EXPECT_EQ(100, result_200p
.pixel_width());
240 EXPECT_EQ(200, result_200p
.pixel_height());
241 EXPECT_TRUE(result_200p
.unscaled());
242 EXPECT_EQ(1U, image_skia
.image_reps().size());
244 // Get the representation again and make sure it doesn't
245 // generate new image skia rep.
246 image_skia
.GetRepresentation(1.0f
);
247 image_skia
.GetRepresentation(2.0f
);
248 EXPECT_EQ(1U, image_skia
.image_reps().size());
251 TEST_F(ImageSkiaTest
, DynamicSource
) {
252 ImageSkia
image_skia(new DynamicSource(Size(100, 200)), Size(100, 200));
253 EXPECT_EQ(0U, image_skia
.image_reps().size());
254 const ImageSkiaRep
& result_100p
= image_skia
.GetRepresentation(1.0f
);
255 EXPECT_EQ(100, result_100p
.GetWidth());
256 EXPECT_EQ(200, result_100p
.GetHeight());
257 EXPECT_EQ(1.0f
, result_100p
.scale());
258 EXPECT_EQ(1U, image_skia
.image_reps().size());
260 const ImageSkiaRep
& result_200p
=
261 image_skia
.GetRepresentation(2.0f
);
262 EXPECT_EQ(100, result_200p
.GetWidth());
263 EXPECT_EQ(200, result_200p
.GetHeight());
264 EXPECT_EQ(200, result_200p
.pixel_width());
265 EXPECT_EQ(400, result_200p
.pixel_height());
266 EXPECT_EQ(2.0f
, result_200p
.scale());
267 EXPECT_EQ(2U, image_skia
.image_reps().size());
269 // Get the representation again and make sure it doesn't
270 // generate new image skia rep.
271 image_skia
.GetRepresentation(1.0f
);
272 EXPECT_EQ(2U, image_skia
.image_reps().size());
273 image_skia
.GetRepresentation(2.0f
);
274 EXPECT_EQ(2U, image_skia
.image_reps().size());
277 // Tests that image_reps returns all of the representations in the
278 // image when there are multiple representations for a scale factor.
279 // This currently is the case with ImageLoader::LoadImages.
280 TEST_F(ImageSkiaTest
, ManyRepsPerScaleFactor
) {
281 const int kSmallIcon1x
= 16;
282 const int kSmallIcon2x
= 32;
283 const int kLargeIcon1x
= 32;
285 ImageSkia
image(new NullSource(), gfx::Size(kSmallIcon1x
, kSmallIcon1x
));
286 // Simulate a source which loads images on a delay. Upon
287 // GetImageForScaleFactor, it immediately returns null and starts loading
288 // image reps slowly.
289 image
.GetRepresentation(1.0f
);
290 image
.GetRepresentation(2.0f
);
292 // After a lengthy amount of simulated time, finally loaded image reps.
293 image
.AddRepresentation(ImageSkiaRep(
294 gfx::Size(kSmallIcon1x
, kSmallIcon1x
), 1.0f
));
295 image
.AddRepresentation(ImageSkiaRep(
296 gfx::Size(kSmallIcon2x
, kSmallIcon2x
), 2.0f
));
297 image
.AddRepresentation(ImageSkiaRep(
298 gfx::Size(kLargeIcon1x
, kLargeIcon1x
), 1.0f
));
300 std::vector
<ImageSkiaRep
> image_reps
= image
.image_reps();
301 EXPECT_EQ(3u, image_reps
.size());
305 for (size_t i
= 0; i
< image_reps
.size(); ++i
) {
306 if (image_reps
[i
].scale() == 1.0f
)
308 else if (image_reps
[i
].scale() == 2.0f
)
311 EXPECT_EQ(2, num_1x
);
312 EXPECT_EQ(1, num_2x
);
315 TEST_F(ImageSkiaTest
, GetBitmap
) {
316 ImageSkia
image_skia(new DynamicSource(Size(100, 200)), Size(100, 200));
317 const SkBitmap
* bitmap
= image_skia
.bitmap();
318 EXPECT_NE(static_cast<SkBitmap
*>(NULL
), bitmap
);
319 EXPECT_FALSE(bitmap
->isNull());
322 TEST_F(ImageSkiaTest
, GetBitmapFromEmpty
) {
323 // Create an image with 1 representation and remove it so the ImageSkiaStorage
324 // is left with no representations.
325 ImageSkia
empty_image(ImageSkiaRep(Size(100, 200), 1.0f
));
326 ImageSkia
empty_image_copy(empty_image
);
327 empty_image
.RemoveRepresentation(1.0f
);
329 // Check that ImageSkia::bitmap() still returns a valid SkBitmap pointer for
330 // the image and all its copies.
331 const SkBitmap
* bitmap
= empty_image_copy
.bitmap();
332 ASSERT_NE(static_cast<SkBitmap
*>(NULL
), bitmap
);
333 EXPECT_TRUE(bitmap
->isNull());
334 EXPECT_TRUE(bitmap
->empty());
337 TEST_F(ImageSkiaTest
, BackedBySameObjectAs
) {
338 // Null images should all be backed by the same object (NULL).
341 EXPECT_TRUE(image
.BackedBySameObjectAs(unrelated
));
343 image
.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
345 ImageSkia copy
= image
;
346 copy
.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
348 unrelated
.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
350 EXPECT_TRUE(image
.BackedBySameObjectAs(copy
));
351 EXPECT_FALSE(image
.BackedBySameObjectAs(unrelated
));
352 EXPECT_FALSE(copy
.BackedBySameObjectAs(unrelated
));
355 #if ENABLE_NON_THREAD_SAFE
356 TEST_F(ImageSkiaTest
, EmptyOnThreadTest
) {
358 test::TestOnThread
empty_on_thread(&empty
);
359 empty_on_thread
.Start();
360 empty_on_thread
.Join();
361 EXPECT_TRUE(empty_on_thread
.can_read());
362 EXPECT_TRUE(empty_on_thread
.can_modify());
365 TEST_F(ImageSkiaTest
, StaticOnThreadTest
) {
366 ImageSkia
image(ImageSkiaRep(Size(100, 200), 1.0f
));
367 EXPECT_FALSE(image
.IsThreadSafe());
369 test::TestOnThread
image_on_thread(&image
);
370 // an image that was never accessed on this thread can be
371 // read by other thread.
372 image_on_thread
.StartAndJoin();
373 EXPECT_TRUE(image_on_thread
.can_read());
374 EXPECT_TRUE(image_on_thread
.can_modify());
375 EXPECT_FALSE(image
.CanRead());
376 EXPECT_FALSE(image
.CanModify());
378 image
.DetachStorageFromThread();
379 // An image is accessed by this thread,
380 // so other thread cannot read/modify it.
382 test::TestOnThread
image_on_thread2(&image
);
383 image_on_thread2
.StartAndJoin();
384 EXPECT_FALSE(image_on_thread2
.can_read());
385 EXPECT_FALSE(image_on_thread2
.can_modify());
386 EXPECT_TRUE(image
.CanRead());
387 EXPECT_TRUE(image
.CanModify());
389 image
.DetachStorageFromThread();
390 scoped_ptr
<ImageSkia
> deep_copy(image
.DeepCopy());
391 EXPECT_FALSE(deep_copy
->IsThreadSafe());
392 test::TestOnThread
deepcopy_on_thread(deep_copy
.get());
393 deepcopy_on_thread
.StartAndJoin();
394 EXPECT_TRUE(deepcopy_on_thread
.can_read());
395 EXPECT_TRUE(deepcopy_on_thread
.can_modify());
396 EXPECT_FALSE(deep_copy
->CanRead());
397 EXPECT_FALSE(deep_copy
->CanModify());
399 scoped_ptr
<ImageSkia
> deep_copy2(image
.DeepCopy());
400 EXPECT_EQ(1U, deep_copy2
->image_reps().size());
401 // Access it from current thread so that it can't be
402 // accessed from another thread.
403 deep_copy2
->image_reps();
404 EXPECT_FALSE(deep_copy2
->IsThreadSafe());
405 test::TestOnThread
deepcopy2_on_thread(deep_copy2
.get());
406 deepcopy2_on_thread
.StartAndJoin();
407 EXPECT_FALSE(deepcopy2_on_thread
.can_read());
408 EXPECT_FALSE(deepcopy2_on_thread
.can_modify());
409 EXPECT_TRUE(deep_copy2
->CanRead());
410 EXPECT_TRUE(deep_copy2
->CanModify());
412 image
.DetachStorageFromThread();
414 // A read-only ImageSkia with no source is thread safe.
415 EXPECT_TRUE(image
.IsThreadSafe());
416 test::TestOnThread
readonly_on_thread(&image
);
417 readonly_on_thread
.StartAndJoin();
418 EXPECT_TRUE(readonly_on_thread
.can_read());
419 EXPECT_FALSE(readonly_on_thread
.can_modify());
420 EXPECT_TRUE(image
.CanRead());
421 EXPECT_FALSE(image
.CanModify());
423 image
.DetachStorageFromThread();
424 image
.MakeThreadSafe();
425 EXPECT_TRUE(image
.IsThreadSafe());
426 test::TestOnThread
threadsafe_on_thread(&image
);
427 threadsafe_on_thread
.StartAndJoin();
428 EXPECT_TRUE(threadsafe_on_thread
.can_read());
429 EXPECT_FALSE(threadsafe_on_thread
.can_modify());
430 EXPECT_TRUE(image
.CanRead());
431 EXPECT_FALSE(image
.CanModify());
434 TEST_F(ImageSkiaTest
, SourceOnThreadTest
) {
435 ImageSkia
image(new DynamicSource(Size(100, 200)), Size(100, 200));
436 EXPECT_FALSE(image
.IsThreadSafe());
438 test::TestOnThread
image_on_thread(&image
);
439 image_on_thread
.StartAndJoin();
440 // an image that was never accessed on this thread can be
441 // read by other thread.
442 EXPECT_TRUE(image_on_thread
.can_read());
443 EXPECT_TRUE(image_on_thread
.can_modify());
444 EXPECT_FALSE(image
.CanRead());
445 EXPECT_FALSE(image
.CanModify());
447 image
.DetachStorageFromThread();
448 // An image is accessed by this thread,
449 // so other thread cannot read/modify it.
451 test::TestOnThread
image_on_thread2(&image
);
452 image_on_thread2
.StartAndJoin();
453 EXPECT_FALSE(image_on_thread2
.can_read());
454 EXPECT_FALSE(image_on_thread2
.can_modify());
455 EXPECT_TRUE(image
.CanRead());
456 EXPECT_TRUE(image
.CanModify());
458 image
.DetachStorageFromThread();
460 EXPECT_FALSE(image
.IsThreadSafe());
461 test::TestOnThread
readonly_on_thread(&image
);
462 readonly_on_thread
.StartAndJoin();
463 EXPECT_TRUE(readonly_on_thread
.can_read());
464 EXPECT_FALSE(readonly_on_thread
.can_modify());
465 EXPECT_FALSE(image
.CanRead());
466 EXPECT_FALSE(image
.CanModify());
468 image
.DetachStorageFromThread();
469 image
.MakeThreadSafe();
470 EXPECT_TRUE(image
.IsThreadSafe());
471 // Check if image reps are generated for supported scale factors.
472 EXPECT_EQ(ImageSkia::GetSupportedScales().size(),
473 image
.image_reps().size());
474 test::TestOnThread
threadsafe_on_thread(&image
);
475 threadsafe_on_thread
.StartAndJoin();
476 EXPECT_TRUE(threadsafe_on_thread
.can_read());
477 EXPECT_FALSE(threadsafe_on_thread
.can_modify());
478 EXPECT_TRUE(image
.CanRead());
479 EXPECT_FALSE(image
.CanModify());
481 #endif // ENABLE_NON_THREAD_SAFE
483 // Just in case we ever get lumped together with other compilation units.
484 #undef ENABLE_NON_THREAD_SAFE
486 TEST_F(ImageSkiaTest
, Unscaled
) {
489 // An ImageSkia created with 1x bitmap is unscaled.
490 ImageSkia image_skia
= ImageSkia::CreateFrom1xBitmap(bitmap
);
491 EXPECT_TRUE(image_skia
.GetRepresentation(1.0f
).unscaled());
492 ImageSkiaRep
rep_2x(Size(100, 100), 2.0f
);
494 // When reps for other scales are added, the unscaled image
496 image_skia
.AddRepresentation(rep_2x
);
497 EXPECT_FALSE(image_skia
.GetRepresentation(1.0f
).unscaled());
498 EXPECT_FALSE(image_skia
.GetRepresentation(2.0f
).unscaled());
503 std::vector
<float> GetSortedScaleFactors(const gfx::ImageSkia
& image
) {
504 const std::vector
<ImageSkiaRep
>& image_reps
= image
.image_reps();
505 std::vector
<float> scale_factors
;
506 for (size_t i
= 0; i
< image_reps
.size(); ++i
) {
507 scale_factors
.push_back(image_reps
[i
].scale());
509 std::sort(scale_factors
.begin(), scale_factors
.end());
510 return scale_factors
;
515 TEST_F(ImageSkiaTest
, ArbitraryScaleFactor
) {
516 // source is owned by |image|
517 DynamicSource
* source
= new DynamicSource(Size(100, 200));
518 ImageSkia
image(source
, gfx::Size(100, 200));
520 image
.GetRepresentation(1.5f
);
521 EXPECT_EQ(2.0f
, source
->GetLastRequestedScaleAndReset());
522 std::vector
<ImageSkiaRep
> image_reps
= image
.image_reps();
523 EXPECT_EQ(2u, image_reps
.size());
525 std::vector
<float> scale_factors
= GetSortedScaleFactors(image
);
526 EXPECT_EQ(1.5f
, scale_factors
[0]);
527 EXPECT_EQ(2.0f
, scale_factors
[1]);
529 // Requesting 1.75 scale factor also falls back to 2.0f and rescale.
530 // However, the image already has the 2.0f data, so it won't fetch again.
531 image
.GetRepresentation(1.75f
);
532 EXPECT_EQ(0.0f
, source
->GetLastRequestedScaleAndReset());
533 image_reps
= image
.image_reps();
534 EXPECT_EQ(3u, image_reps
.size());
536 scale_factors
= GetSortedScaleFactors(image
);
537 EXPECT_EQ(1.5f
, scale_factors
[0]);
538 EXPECT_EQ(1.75f
, scale_factors
[1]);
539 EXPECT_EQ(2.0f
, scale_factors
[2]);
541 // Requesting 1.25 scale factor also falls back to 2.0f and rescale.
542 // However, the image already has the 2.0f data, so it won't fetch again.
543 image
.GetRepresentation(1.25f
);
544 EXPECT_EQ(0.0f
, source
->GetLastRequestedScaleAndReset());
545 image_reps
= image
.image_reps();
546 EXPECT_EQ(4u, image_reps
.size());
547 scale_factors
= GetSortedScaleFactors(image
);
548 EXPECT_EQ(1.25f
, scale_factors
[0]);
549 EXPECT_EQ(1.5f
, scale_factors
[1]);
550 EXPECT_EQ(1.75f
, scale_factors
[2]);
551 EXPECT_EQ(2.0f
, scale_factors
[3]);
553 // 1.20 is falled back to 1.0.
554 image
.GetRepresentation(1.20f
);
555 EXPECT_EQ(1.0f
, source
->GetLastRequestedScaleAndReset());
556 image_reps
= image
.image_reps();
557 EXPECT_EQ(6u, image_reps
.size());
558 scale_factors
= GetSortedScaleFactors(image
);
559 EXPECT_EQ(1.0f
, scale_factors
[0]);
560 EXPECT_EQ(1.2f
, scale_factors
[1]);
561 EXPECT_EQ(1.25f
, scale_factors
[2]);
562 EXPECT_EQ(1.5f
, scale_factors
[3]);
563 EXPECT_EQ(1.75f
, scale_factors
[4]);
564 EXPECT_EQ(2.0f
, scale_factors
[5]);
566 // Scale factor less than 1.0f will be falled back to 1.0f
567 image
.GetRepresentation(0.75f
);
568 EXPECT_EQ(0.0f
, source
->GetLastRequestedScaleAndReset());
569 image_reps
= image
.image_reps();
570 EXPECT_EQ(7u, image_reps
.size());
572 scale_factors
= GetSortedScaleFactors(image
);
573 EXPECT_EQ(0.75f
, scale_factors
[0]);
574 EXPECT_EQ(1.0f
, scale_factors
[1]);
575 EXPECT_EQ(1.2f
, scale_factors
[2]);
576 EXPECT_EQ(1.25f
, scale_factors
[3]);
577 EXPECT_EQ(1.5f
, scale_factors
[4]);
578 EXPECT_EQ(1.75f
, scale_factors
[5]);
579 EXPECT_EQ(2.0f
, scale_factors
[6]);
581 // Scale factor greater than 2.0f is falled back to 2.0f because it's not
583 image
.GetRepresentation(3.0f
);
584 EXPECT_EQ(0.0f
, source
->GetLastRequestedScaleAndReset());
585 image_reps
= image
.image_reps();
586 EXPECT_EQ(8u, image_reps
.size());
589 TEST_F(ImageSkiaTest
, ArbitraryScaleFactorWithMissingResource
) {
590 ImageSkia
image(new FixedScaleSource(
591 ImageSkiaRep(Size(100, 200), 1.0f
)), Size(100, 200));
593 // Requesting 1.5f -- falls back to 2.0f, but couldn't find. It should
594 // look up 1.0f and then rescale it. Note that the rescaled ImageSkiaRep will
596 const ImageSkiaRep
& rep
= image
.GetRepresentation(1.5f
);
597 EXPECT_EQ(1.5f
, rep
.scale());
598 EXPECT_EQ(2U, image
.image_reps().size());
599 EXPECT_EQ(2.0f
, image
.image_reps()[0].scale());
600 EXPECT_EQ(1.5f
, image
.image_reps()[1].scale());
603 TEST_F(ImageSkiaTest
, UnscaledImageForArbitraryScaleFactor
) {
604 // 0.0f means unscaled.
605 ImageSkia
image(new FixedScaleSource(
606 ImageSkiaRep(Size(100, 200), 0.0f
)), Size(100, 200));
608 // Requesting 2.0f, which should return 1.0f unscaled image.
609 const ImageSkiaRep
& rep
= image
.GetRepresentation(2.0f
);
610 EXPECT_EQ(1.0f
, rep
.scale());
611 EXPECT_EQ("100x200", rep
.pixel_size().ToString());
612 EXPECT_TRUE(rep
.unscaled());
613 EXPECT_EQ(1U, image
.image_reps().size());
615 // Same for any other scale factors.
616 const ImageSkiaRep
& rep15
= image
.GetRepresentation(1.5f
);
617 EXPECT_EQ(1.0f
, rep15
.scale());
618 EXPECT_EQ("100x200", rep15
.pixel_size().ToString());
619 EXPECT_TRUE(rep15
.unscaled());
620 EXPECT_EQ(1U, image
.image_reps().size());
622 const ImageSkiaRep
& rep12
= image
.GetRepresentation(1.2f
);
623 EXPECT_EQ(1.0f
, rep12
.scale());
624 EXPECT_EQ("100x200", rep12
.pixel_size().ToString());
625 EXPECT_TRUE(rep12
.unscaled());
626 EXPECT_EQ(1U, image
.image_reps().size());