| 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 "chrome/browser/extensions/extension_icon_image.h" | 5 #include "extensions/browser/extension_icon_image.h" |
| 6 | 6 |
| 7 #include "base/json/json_file_value_serializer.h" | 7 #include "base/json/json_file_value_serializer.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
| 10 #include "chrome/browser/extensions/image_loader.h" | |
| 11 #include "chrome/common/chrome_paths.h" | 10 #include "chrome/common/chrome_paths.h" |
| 12 #include "chrome/common/extensions/extension_constants.h" | |
| 13 #include "chrome/test/base/testing_profile.h" | 11 #include "chrome/test/base/testing_profile.h" |
| 14 #include "content/public/test/test_browser_thread.h" | 12 #include "content/public/test/test_browser_thread.h" |
| 13 #include "extensions/browser/image_loader.h" |
| 15 #include "extensions/common/extension.h" | 14 #include "extensions/common/extension.h" |
| 16 #include "extensions/common/manifest.h" | 15 #include "extensions/common/manifest.h" |
| 17 #include "extensions/common/manifest_handlers/icons_handler.h" | 16 #include "extensions/common/manifest_handlers/icons_handler.h" |
| 18 #include "grit/theme_resources.h" | |
| 19 #include "skia/ext/image_operations.h" | 17 #include "skia/ext/image_operations.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "ui/base/resource/resource_bundle.h" | 19 #include "ui/base/resource/resource_bundle.h" |
| 22 #include "ui/gfx/image/image_skia_source.h" | 20 #include "ui/gfx/image/image_skia_source.h" |
| 23 #include "ui/gfx/skia_util.h" | 21 #include "ui/gfx/skia_util.h" |
| 24 | 22 |
| 25 using content::BrowserThread; | 23 using content::BrowserThread; |
| 26 using extensions::Extension; | 24 using extensions::Extension; |
| 27 using extensions::IconImage; | 25 using extensions::IconImage; |
| 28 using extensions::Manifest; | 26 using extensions::Manifest; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 173 } |
| 176 | 174 |
| 177 // IconImage::Delegate overrides: | 175 // IconImage::Delegate overrides: |
| 178 virtual void OnExtensionIconImageChanged(IconImage* image) OVERRIDE { | 176 virtual void OnExtensionIconImageChanged(IconImage* image) OVERRIDE { |
| 179 image_loaded_count_++; | 177 image_loaded_count_++; |
| 180 if (quit_in_image_loaded_) | 178 if (quit_in_image_loaded_) |
| 181 base::MessageLoop::current()->Quit(); | 179 base::MessageLoop::current()->Quit(); |
| 182 } | 180 } |
| 183 | 181 |
| 184 gfx::ImageSkia GetDefaultIcon() { | 182 gfx::ImageSkia GetDefaultIcon() { |
| 185 return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 183 return gfx::ImageSkia(gfx::ImageSkiaRep(gfx::Size(16, 16), 1.0f)); |
| 186 IDR_EXTENSIONS_FAVICON); | |
| 187 } | 184 } |
| 188 | 185 |
| 189 // Loads an image to be used in test from the extension. | 186 // Loads an image to be used in test from the extension. |
| 190 // The image will be loaded from the relative path |path|. | 187 // The image will be loaded from the relative path |path|. |
| 191 SkBitmap GetTestBitmap(const Extension* extension, | 188 SkBitmap GetTestBitmap(const Extension* extension, |
| 192 const std::string& path, | 189 const std::string& path, |
| 193 int size) { | 190 int size) { |
| 194 TestImageLoader image_loader(extension); | 191 TestImageLoader image_loader(extension); |
| 195 return image_loader.LoadBitmap(path, size); | 192 return image_loader.LoadBitmap(path, size); |
| 196 } | 193 } |
| 197 | 194 |
| 198 private: | 195 private: |
| 199 int image_loaded_count_; | 196 int image_loaded_count_; |
| 200 bool quit_in_image_loaded_; | 197 bool quit_in_image_loaded_; |
| 201 base::MessageLoop ui_loop_; | 198 base::MessageLoop ui_loop_; |
| 202 content::TestBrowserThread ui_thread_; | 199 content::TestBrowserThread ui_thread_; |
| 203 content::TestBrowserThread file_thread_; | 200 content::TestBrowserThread file_thread_; |
| 204 content::TestBrowserThread io_thread_; | 201 content::TestBrowserThread io_thread_; |
| 205 | 202 |
| 206 DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); | 203 DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); |
| 207 }; | 204 }; |
| 208 | 205 |
| 209 } // namespace | 206 } // namespace |
| 210 | 207 |
| 211 TEST_F(ExtensionIconImageTest, Basic) { | 208 TEST_F(ExtensionIconImageTest, Basic) { |
| 212 std::vector<ui::ScaleFactor> supported_factors; | 209 std::vector<ui::ScaleFactor> supported_factors; |
| 213 supported_factors.push_back(ui::SCALE_FACTOR_100P); | 210 supported_factors.push_back(ui::SCALE_FACTOR_100P); |
| 214 supported_factors.push_back(ui::SCALE_FACTOR_200P); | 211 supported_factors.push_back(ui::SCALE_FACTOR_200P); |
| 215 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); | 212 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); |
| 216 scoped_ptr<Profile> profile(new TestingProfile()); | 213 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 217 scoped_refptr<Extension> extension(CreateExtension( | 214 scoped_refptr<Extension> extension(CreateExtension( |
| 218 "extension_icon_image", Manifest::INVALID_LOCATION)); | 215 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 219 ASSERT_TRUE(extension.get() != NULL); | 216 ASSERT_TRUE(extension.get() != NULL); |
| 220 | 217 |
| 221 gfx::ImageSkia default_icon = GetDefaultIcon(); | 218 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 222 | 219 |
| 223 // Load images we expect to find as representations in icon_image, so we | 220 // Load images we expect to find as representations in icon_image, so we |
| 224 // can later use them to validate icon_image. | 221 // can later use them to validate icon_image. |
| 225 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); | 222 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); |
| 226 ASSERT_FALSE(bitmap_16.empty()); | 223 ASSERT_FALSE(bitmap_16.empty()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 bitmap_48_resized_to_32)); | 277 bitmap_48_resized_to_32)); |
| 281 } | 278 } |
| 282 | 279 |
| 283 // There is no resource with either exact or bigger size, but there is a smaller | 280 // There is no resource with either exact or bigger size, but there is a smaller |
| 284 // resource. | 281 // resource. |
| 285 TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) { | 282 TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) { |
| 286 std::vector<ui::ScaleFactor> supported_factors; | 283 std::vector<ui::ScaleFactor> supported_factors; |
| 287 supported_factors.push_back(ui::SCALE_FACTOR_100P); | 284 supported_factors.push_back(ui::SCALE_FACTOR_100P); |
| 288 supported_factors.push_back(ui::SCALE_FACTOR_200P); | 285 supported_factors.push_back(ui::SCALE_FACTOR_200P); |
| 289 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); | 286 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); |
| 290 scoped_ptr<Profile> profile(new TestingProfile()); | 287 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 291 scoped_refptr<Extension> extension(CreateExtension( | 288 scoped_refptr<Extension> extension(CreateExtension( |
| 292 "extension_icon_image", Manifest::INVALID_LOCATION)); | 289 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 293 ASSERT_TRUE(extension.get() != NULL); | 290 ASSERT_TRUE(extension.get() != NULL); |
| 294 | 291 |
| 295 gfx::ImageSkia default_icon = GetDefaultIcon(); | 292 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 296 | 293 |
| 297 // Load images we expect to find as representations in icon_image, so we | 294 // Load images we expect to find as representations in icon_image, so we |
| 298 // can later use them to validate icon_image. | 295 // can later use them to validate icon_image. |
| 299 SkBitmap bitmap_48 = GetTestBitmap(extension.get(), "48.png", 48); | 296 SkBitmap bitmap_48 = GetTestBitmap(extension.get(), "48.png", 48); |
| 300 ASSERT_FALSE(bitmap_48.empty()); | 297 ASSERT_FALSE(bitmap_48.empty()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 319 EXPECT_EQ(2.0f, representation.scale()); | 316 EXPECT_EQ(2.0f, representation.scale()); |
| 320 EXPECT_EQ(64, representation.pixel_width()); | 317 EXPECT_EQ(64, representation.pixel_width()); |
| 321 EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), | 318 EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), |
| 322 EnsureBitmapSize(bitmap_48, 64))); | 319 EnsureBitmapSize(bitmap_48, 64))); |
| 323 } | 320 } |
| 324 | 321 |
| 325 // There is no resource with exact size, but there is a smaller and a bigger | 322 // There is no resource with exact size, but there is a smaller and a bigger |
| 326 // one. Requested size is smaller than 32 though, so the smaller resource should | 323 // one. Requested size is smaller than 32 though, so the smaller resource should |
| 327 // be loaded. | 324 // be loaded. |
| 328 TEST_F(ExtensionIconImageTest, FallbackToSmaller) { | 325 TEST_F(ExtensionIconImageTest, FallbackToSmaller) { |
| 329 scoped_ptr<Profile> profile(new TestingProfile()); | 326 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 330 scoped_refptr<Extension> extension(CreateExtension( | 327 scoped_refptr<Extension> extension(CreateExtension( |
| 331 "extension_icon_image", Manifest::INVALID_LOCATION)); | 328 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 332 ASSERT_TRUE(extension.get() != NULL); | 329 ASSERT_TRUE(extension.get() != NULL); |
| 333 | 330 |
| 334 gfx::ImageSkia default_icon = GetDefaultIcon(); | 331 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 335 | 332 |
| 336 // Load images we expect to find as representations in icon_image, so we | 333 // Load images we expect to find as representations in icon_image, so we |
| 337 // can later use them to validate icon_image. | 334 // can later use them to validate icon_image. |
| 338 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); | 335 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); |
| 339 ASSERT_FALSE(bitmap_16.empty()); | 336 ASSERT_FALSE(bitmap_16.empty()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 356 // We should have loaded smaller (resized) resource. | 353 // We should have loaded smaller (resized) resource. |
| 357 EXPECT_EQ(1.0f, representation.scale()); | 354 EXPECT_EQ(1.0f, representation.scale()); |
| 358 EXPECT_EQ(17, representation.pixel_width()); | 355 EXPECT_EQ(17, representation.pixel_width()); |
| 359 EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), | 356 EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), |
| 360 EnsureBitmapSize(bitmap_16, 17))); | 357 EnsureBitmapSize(bitmap_16, 17))); |
| 361 } | 358 } |
| 362 | 359 |
| 363 // If resource set is empty, |GetRepresentation| should synchronously return | 360 // If resource set is empty, |GetRepresentation| should synchronously return |
| 364 // default icon, without notifying observer of image change. | 361 // default icon, without notifying observer of image change. |
| 365 TEST_F(ExtensionIconImageTest, NoResources) { | 362 TEST_F(ExtensionIconImageTest, NoResources) { |
| 366 scoped_ptr<Profile> profile(new TestingProfile()); | 363 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 367 scoped_refptr<Extension> extension(CreateExtension( | 364 scoped_refptr<Extension> extension(CreateExtension( |
| 368 "extension_icon_image", Manifest::INVALID_LOCATION)); | 365 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 369 ASSERT_TRUE(extension.get() != NULL); | 366 ASSERT_TRUE(extension.get() != NULL); |
| 370 | 367 |
| 371 ExtensionIconSet empty_icon_set; | 368 ExtensionIconSet empty_icon_set; |
| 372 gfx::ImageSkia default_icon = GetDefaultIcon(); | 369 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 373 | 370 |
| 374 const int kRequestedSize = 24; | 371 const int kRequestedSize = 24; |
| 375 IconImage image(profile.get(), | 372 IconImage image(profile.get(), |
| 376 extension.get(), | 373 extension.get(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 395 representation.sk_bitmap(), | 392 representation.sk_bitmap(), |
| 396 EnsureBitmapSize( | 393 EnsureBitmapSize( |
| 397 default_icon.GetRepresentation(1.0f).sk_bitmap(), | 394 default_icon.GetRepresentation(1.0f).sk_bitmap(), |
| 398 kRequestedSize))); | 395 kRequestedSize))); |
| 399 } | 396 } |
| 400 | 397 |
| 401 // If resource set is invalid, image load should be done asynchronously and | 398 // If resource set is invalid, image load should be done asynchronously and |
| 402 // the observer should be notified when it's done. |GetRepresentation| should | 399 // the observer should be notified when it's done. |GetRepresentation| should |
| 403 // return the default icon representation once image load is done. | 400 // return the default icon representation once image load is done. |
| 404 TEST_F(ExtensionIconImageTest, InvalidResource) { | 401 TEST_F(ExtensionIconImageTest, InvalidResource) { |
| 405 scoped_ptr<Profile> profile(new TestingProfile()); | 402 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 406 scoped_refptr<Extension> extension(CreateExtension( | 403 scoped_refptr<Extension> extension(CreateExtension( |
| 407 "extension_icon_image", Manifest::INVALID_LOCATION)); | 404 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 408 ASSERT_TRUE(extension.get() != NULL); | 405 ASSERT_TRUE(extension.get() != NULL); |
| 409 | 406 |
| 410 const int kInvalidIconSize = 24; | 407 const int kInvalidIconSize = 24; |
| 411 ExtensionIconSet invalid_icon_set; | 408 ExtensionIconSet invalid_icon_set; |
| 412 invalid_icon_set.Add(kInvalidIconSize, "invalid.png"); | 409 invalid_icon_set.Add(kInvalidIconSize, "invalid.png"); |
| 413 | 410 |
| 414 gfx::ImageSkia default_icon = GetDefaultIcon(); | 411 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 415 | 412 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 434 EXPECT_TRUE(gfx::BitmapsAreEqual( | 431 EXPECT_TRUE(gfx::BitmapsAreEqual( |
| 435 representation.sk_bitmap(), | 432 representation.sk_bitmap(), |
| 436 EnsureBitmapSize( | 433 EnsureBitmapSize( |
| 437 default_icon.GetRepresentation(1.0f).sk_bitmap(), | 434 default_icon.GetRepresentation(1.0f).sk_bitmap(), |
| 438 kInvalidIconSize))); | 435 kInvalidIconSize))); |
| 439 } | 436 } |
| 440 | 437 |
| 441 // Test that IconImage works with lazily (but synchronously) created default | 438 // Test that IconImage works with lazily (but synchronously) created default |
| 442 // icon when IconImage returns synchronously. | 439 // icon when IconImage returns synchronously. |
| 443 TEST_F(ExtensionIconImageTest, LazyDefaultIcon) { | 440 TEST_F(ExtensionIconImageTest, LazyDefaultIcon) { |
| 444 scoped_ptr<Profile> profile(new TestingProfile()); | 441 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 445 scoped_refptr<Extension> extension(CreateExtension( | 442 scoped_refptr<Extension> extension(CreateExtension( |
| 446 "extension_icon_image", Manifest::INVALID_LOCATION)); | 443 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 447 ASSERT_TRUE(extension.get() != NULL); | 444 ASSERT_TRUE(extension.get() != NULL); |
| 448 | 445 |
| 449 gfx::ImageSkia default_icon = GetDefaultIcon(); | 446 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 450 gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), | 447 gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), |
| 451 default_icon.size()); | 448 default_icon.size()); |
| 452 | 449 |
| 453 ExtensionIconSet empty_icon_set; | 450 ExtensionIconSet empty_icon_set; |
| 454 | 451 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 472 default_icon.GetRepresentation(1.0f).sk_bitmap(), | 469 default_icon.GetRepresentation(1.0f).sk_bitmap(), |
| 473 kRequestedSize))); | 470 kRequestedSize))); |
| 474 | 471 |
| 475 // We should have a default icon representation. | 472 // We should have a default icon representation. |
| 476 ASSERT_EQ(1u, image.image_skia().image_reps().size()); | 473 ASSERT_EQ(1u, image.image_skia().image_reps().size()); |
| 477 } | 474 } |
| 478 | 475 |
| 479 // Test that IconImage works with lazily (but synchronously) created default | 476 // Test that IconImage works with lazily (but synchronously) created default |
| 480 // icon when IconImage returns asynchronously. | 477 // icon when IconImage returns asynchronously. |
| 481 TEST_F(ExtensionIconImageTest, LazyDefaultIcon_AsyncIconImage) { | 478 TEST_F(ExtensionIconImageTest, LazyDefaultIcon_AsyncIconImage) { |
| 482 scoped_ptr<Profile> profile(new TestingProfile()); | 479 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 483 scoped_refptr<Extension> extension(CreateExtension( | 480 scoped_refptr<Extension> extension(CreateExtension( |
| 484 "extension_icon_image", Manifest::INVALID_LOCATION)); | 481 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 485 ASSERT_TRUE(extension.get() != NULL); | 482 ASSERT_TRUE(extension.get() != NULL); |
| 486 | 483 |
| 487 gfx::ImageSkia default_icon = GetDefaultIcon(); | 484 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 488 gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), | 485 gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), |
| 489 default_icon.size()); | 486 default_icon.size()); |
| 490 | 487 |
| 491 const int kInvalidIconSize = 24; | 488 const int kInvalidIconSize = 24; |
| 492 ExtensionIconSet invalid_icon_set; | 489 ExtensionIconSet invalid_icon_set; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 516 EnsureBitmapSize( | 513 EnsureBitmapSize( |
| 517 default_icon.GetRepresentation(1.0f).sk_bitmap(), | 514 default_icon.GetRepresentation(1.0f).sk_bitmap(), |
| 518 kInvalidIconSize))); | 515 kInvalidIconSize))); |
| 519 } | 516 } |
| 520 | 517 |
| 521 // Tests behavior of image created by IconImage after IconImage host goes | 518 // Tests behavior of image created by IconImage after IconImage host goes |
| 522 // away. The image should still return loaded representations. If requested | 519 // away. The image should still return loaded representations. If requested |
| 523 // representation was not loaded while IconImage host was around, transparent | 520 // representation was not loaded while IconImage host was around, transparent |
| 524 // representations should be returned. | 521 // representations should be returned. |
| 525 TEST_F(ExtensionIconImageTest, IconImageDestruction) { | 522 TEST_F(ExtensionIconImageTest, IconImageDestruction) { |
| 526 scoped_ptr<Profile> profile(new TestingProfile()); | 523 scoped_ptr<content::BrowserContext> profile(new TestingProfile()); |
| 527 scoped_refptr<Extension> extension(CreateExtension( | 524 scoped_refptr<Extension> extension(CreateExtension( |
| 528 "extension_icon_image", Manifest::INVALID_LOCATION)); | 525 "extension_icon_image", Manifest::INVALID_LOCATION)); |
| 529 ASSERT_TRUE(extension.get() != NULL); | 526 ASSERT_TRUE(extension.get() != NULL); |
| 530 | 527 |
| 531 gfx::ImageSkia default_icon = GetDefaultIcon(); | 528 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 532 | 529 |
| 533 // Load images we expect to find as representations in icon_image, so we | 530 // Load images we expect to find as representations in icon_image, so we |
| 534 // can later use them to validate icon_image. | 531 // can later use them to validate icon_image. |
| 535 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); | 532 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); |
| 536 ASSERT_FALSE(bitmap_16.empty()); | 533 ASSERT_FALSE(bitmap_16.empty()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 565 | 562 |
| 566 // When requesting another representation, we should not crash and return some | 563 // When requesting another representation, we should not crash and return some |
| 567 // image of the size. It could be blank or a rescale from the existing 1.0f | 564 // image of the size. It could be blank or a rescale from the existing 1.0f |
| 568 // icon. | 565 // icon. |
| 569 representation = image_skia.GetRepresentation(2.0f); | 566 representation = image_skia.GetRepresentation(2.0f); |
| 570 | 567 |
| 571 EXPECT_EQ(16, representation.GetWidth()); | 568 EXPECT_EQ(16, representation.GetWidth()); |
| 572 EXPECT_EQ(16, representation.GetHeight()); | 569 EXPECT_EQ(16, representation.GetHeight()); |
| 573 EXPECT_EQ(2.0f, representation.scale()); | 570 EXPECT_EQ(2.0f, representation.scale()); |
| 574 } | 571 } |
| OLD | NEW |