color_transform_unittest.cc 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // Copyright 2019 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.
  4. #include "ui/color/color_transform.h"
  5. #include "testing/gtest/include/gtest/gtest.h"
  6. #include "ui/color/color_mixer.h"
  7. #include "ui/color/color_recipe.h"
  8. #include "ui/color/color_test_ids.h"
  9. #include "ui/gfx/color_palette.h"
  10. namespace ui {
  11. namespace {
  12. // Tests initialization with an SkColor value.
  13. TEST(ColorRecipeTest, TestColorRecipeInitialization) {
  14. const auto verify_initialization = [&](SkColor color) {
  15. ColorTransform transform = color;
  16. EXPECT_EQ(color, transform.Run(SK_ColorBLACK, ColorMixer()));
  17. };
  18. verify_initialization(SK_ColorBLUE);
  19. verify_initialization(SK_ColorRED);
  20. verify_initialization(SK_ColorGREEN);
  21. }
  22. // Tests that AlphaBlend() produces a transform that blends its inputs.
  23. TEST(ColorTransformTest, AlphaBlend) {
  24. const auto blend = [](SkAlpha alpha) {
  25. const ColorTransform transform =
  26. AlphaBlend(SK_ColorWHITE, SK_ColorBLACK, alpha);
  27. return transform.Run(gfx::kPlaceholderColor, ColorMixer());
  28. };
  29. EXPECT_EQ(SK_ColorBLACK, blend(SK_AlphaTRANSPARENT));
  30. EXPECT_EQ(SK_ColorWHITE, blend(SK_AlphaOPAQUE));
  31. EXPECT_EQ(SK_ColorGRAY, blend(SkColorGetR(SK_ColorGRAY)));
  32. }
  33. // Tests that BlendForMinContrast(), with the default args, produces a transform
  34. // that blends its foreground color to produce readable contrast against its
  35. // background color.
  36. TEST(ColorTransformTest, BlendForMinContrast) {
  37. const ColorTransform transform =
  38. BlendForMinContrast(FromTransformInput(), kColorTest0);
  39. constexpr SkColor kBackground = SK_ColorWHITE;
  40. ColorMixer mixer;
  41. mixer[kColorTest0] = {kBackground};
  42. const auto verify_contrast = [&](SkColor input) {
  43. EXPECT_GE(
  44. color_utils::GetContrastRatio(transform.Run(input, mixer), kBackground),
  45. color_utils::kMinimumReadableContrastRatio);
  46. };
  47. verify_contrast(SK_ColorBLACK);
  48. verify_contrast(SK_ColorWHITE);
  49. verify_contrast(SK_ColorRED);
  50. }
  51. // Tests that BlendForMinContrast() supports optional args, which can be used to
  52. // blend toward a specific foreground color and with a specific minimum contrast
  53. // ratio.
  54. TEST(ColorTransformTest, BlendForMinContrastOptionalArgs) {
  55. constexpr float kMinContrast = 6.0f;
  56. const ColorTransform transform = BlendForMinContrast(
  57. FromTransformInput(), kColorTest0, kColorTest1, kMinContrast);
  58. constexpr SkColor kBackground = SK_ColorWHITE;
  59. ColorMixer mixer;
  60. mixer[kColorTest0] = {kBackground};
  61. mixer[kColorTest1] = {gfx::kGoogleBlue900};
  62. const auto verify_contrast = [&](SkColor input) {
  63. EXPECT_GE(
  64. color_utils::GetContrastRatio(transform.Run(input, mixer), kBackground),
  65. kMinContrast);
  66. };
  67. verify_contrast(SK_ColorBLACK);
  68. verify_contrast(SK_ColorWHITE);
  69. verify_contrast(gfx::kGoogleBlue500);
  70. }
  71. // Tests that BlendForMinContrastWithSelf() produces a transform that blends its
  72. // input color towards the color with max contrast.
  73. TEST(ColorTransformTest, BlendForMinContrastWithSelf) {
  74. constexpr float kContrastRatio = 2;
  75. const ColorTransform transform =
  76. BlendForMinContrastWithSelf(FromTransformInput(), kContrastRatio);
  77. const auto verify_blend = [&](SkColor input) {
  78. const SkColor target = color_utils::GetColorWithMaxContrast(input);
  79. EXPECT_LT(color_utils::GetContrastRatio(transform.Run(input, ColorMixer()),
  80. target),
  81. color_utils::GetContrastRatio(input, target));
  82. };
  83. verify_blend(SK_ColorBLACK);
  84. verify_blend(SK_ColorWHITE);
  85. verify_blend(SK_ColorRED);
  86. }
  87. // Tests that BlendTowardMaxContrast() produces a transform that blends its
  88. // input color towards the color with max contrast.
  89. TEST(ColorTransformTest, BlendTowardMaxContrast) {
  90. constexpr SkAlpha kAlpha = 0x20;
  91. const ColorTransform transform =
  92. BlendTowardMaxContrast(FromTransformInput(), kAlpha);
  93. const auto verify_blend = [&](SkColor input) {
  94. const SkColor target = color_utils::GetColorWithMaxContrast(input);
  95. EXPECT_LT(color_utils::GetContrastRatio(transform.Run(input, ColorMixer()),
  96. target),
  97. color_utils::GetContrastRatio(input, target));
  98. };
  99. verify_blend(SK_ColorBLACK);
  100. verify_blend(SK_ColorWHITE);
  101. verify_blend(SK_ColorRED);
  102. }
  103. // Tests that ContrastInvert() produces a transform that outputs a color with at
  104. // least as much contrast, but against the opposite endpoint.
  105. TEST(ColorTransformTest, ContrastInvert) {
  106. const ColorTransform transform = ContrastInvert(FromTransformInput());
  107. const auto verify_invert = [&](SkColor input) {
  108. const SkColor far_endpoint = color_utils::GetColorWithMaxContrast(input);
  109. const SkColor near_endpoint =
  110. color_utils::GetColorWithMaxContrast(far_endpoint);
  111. EXPECT_GE(color_utils::GetContrastRatio(transform.Run(input, ColorMixer()),
  112. near_endpoint),
  113. color_utils::GetContrastRatio(input, far_endpoint));
  114. };
  115. verify_invert(gfx::kGoogleGrey900);
  116. verify_invert(SK_ColorWHITE);
  117. verify_invert(SK_ColorRED);
  118. verify_invert(gfx::kGoogleBlue500);
  119. }
  120. // Tests that DeriveDefaultIconColor() produces a transform that changes its
  121. // input color.
  122. TEST(ColorTransformTest, DeriveDefaultIconColor) {
  123. const ColorTransform transform = DeriveDefaultIconColor(FromTransformInput());
  124. const auto verify_derive = [&](SkColor input) {
  125. EXPECT_NE(input, transform.Run(input, ColorMixer()));
  126. };
  127. verify_derive(SK_ColorBLACK);
  128. verify_derive(SK_ColorWHITE);
  129. verify_derive(SK_ColorRED);
  130. }
  131. // Tests that initializing a transform from a color produces a transform that
  132. // ignores the input color and always outputs a specified SkColor.
  133. TEST(ColorTransformTest, FromColor) {
  134. constexpr SkColor kOutput = SK_ColorGREEN;
  135. const ColorTransform transform = kOutput;
  136. const auto verify_color = [&](SkColor input) {
  137. EXPECT_EQ(kOutput, transform.Run(input, ColorMixer()));
  138. };
  139. verify_color(SK_ColorBLACK);
  140. verify_color(SK_ColorWHITE);
  141. verify_color(SK_ColorRED);
  142. }
  143. // Tests that a transform created from a ColorId produces a transform that
  144. // ignores the input color and always outputs a specified result color.
  145. TEST(ColorTransformTest, FromColorId) {
  146. const ColorTransform transform = {kColorTest0};
  147. constexpr SkColor kTest1Color = SK_ColorRED;
  148. ColorMixer mixer;
  149. mixer[kColorTest0] = {kColorTest1};
  150. mixer[kColorTest1] = {kTest1Color};
  151. const auto verify_color = [&](SkColor input) {
  152. EXPECT_EQ(kTest1Color, transform.Run(input, mixer));
  153. };
  154. verify_color(SK_ColorBLACK);
  155. verify_color(SK_ColorWHITE);
  156. verify_color(SK_ColorRED);
  157. } // namespace
  158. // Tests that FromTransformInput() returns its input color unmodified.
  159. TEST(ColorTransformTest, FromTransformInput) {
  160. const ColorTransform transform = FromTransformInput();
  161. const auto verify_color = [&](SkColor input) {
  162. EXPECT_EQ(input, transform.Run(input, ColorMixer()));
  163. };
  164. verify_color(SK_ColorBLACK);
  165. verify_color(SK_ColorWHITE);
  166. verify_color(SK_ColorRED);
  167. } // namespace
  168. // Tests that GetColorWithMaxContrast() produces a transform that changes white
  169. // to the darkest color.
  170. TEST(ColorTransformTest, GetColorWithMaxContrast) {
  171. const ColorTransform transform =
  172. GetColorWithMaxContrast(FromTransformInput());
  173. constexpr SkColor kNewDarkestColor = gfx::kGoogleGrey500;
  174. const SkColor default_darkest_color =
  175. color_utils::SetDarkestColorForTesting(kNewDarkestColor);
  176. constexpr SkColor kLightestColor = SK_ColorWHITE;
  177. EXPECT_EQ(kNewDarkestColor, transform.Run(kLightestColor, ColorMixer()));
  178. color_utils::SetDarkestColorForTesting(default_darkest_color);
  179. EXPECT_EQ(default_darkest_color, transform.Run(kLightestColor, ColorMixer()));
  180. }
  181. // Tests that GetResultingPaintColor() produces a transform that composites
  182. // opaquely.
  183. TEST(ColorTransformTest, GetResultingPaintColor) {
  184. const ColorTransform transform =
  185. GetResultingPaintColor(FromTransformInput(), kColorTest0);
  186. constexpr SkColor kBackground = SK_ColorWHITE;
  187. ColorMixer mixer;
  188. mixer[kColorTest0] = {kBackground};
  189. EXPECT_EQ(SK_ColorBLACK, transform.Run(SK_ColorBLACK, mixer));
  190. EXPECT_EQ(kBackground, transform.Run(SK_ColorTRANSPARENT, mixer));
  191. EXPECT_EQ(color_utils::AlphaBlend(SK_ColorBLACK, kBackground, SkAlpha{0x80}),
  192. transform.Run(SkColorSetA(SK_ColorBLACK, 0x80), mixer));
  193. }
  194. // Tests that SelectBasedOnDarkInput() produces a transform that toggles between
  195. // inputs based on whether the input color is dark.
  196. TEST(ColorTransformTest, SelectBasedOnDarkInput) {
  197. constexpr SkColor kDarkOutput = SK_ColorGREEN;
  198. constexpr SkColor kLightOutput = SK_ColorRED;
  199. const ColorTransform transform =
  200. SelectBasedOnDarkInput(FromTransformInput(), kDarkOutput, kLightOutput);
  201. EXPECT_EQ(kDarkOutput, transform.Run(SK_ColorBLACK, ColorMixer()));
  202. EXPECT_EQ(kLightOutput, transform.Run(SK_ColorWHITE, ColorMixer()));
  203. EXPECT_EQ(kDarkOutput, transform.Run(SK_ColorBLUE, ColorMixer()));
  204. EXPECT_EQ(kLightOutput, transform.Run(SK_ColorRED, ColorMixer()));
  205. }
  206. // Tests that SetAlpha() produces a transform that sets its input's alpha.
  207. TEST(ColorTransformTest, SetAlpha) {
  208. constexpr SkAlpha kAlpha = 0x20;
  209. const ColorTransform transform = SetAlpha(FromTransformInput(), kAlpha);
  210. for (auto color : {SK_ColorBLACK, SK_ColorRED, SK_ColorTRANSPARENT})
  211. EXPECT_EQ(SkColorSetA(color, kAlpha), transform.Run(color, ColorMixer()));
  212. }
  213. } // namespace
  214. } // namespace ui