15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColorPriv.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace color_utils {
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ColorUtils, SkColorToHSLRed) {
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL hsl = {0, 0, 0};
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SkColorToHSL(SK_ColorRED, &hsl);
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(hsl.h, 0);
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(hsl.s, 1);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(hsl.l, 0.5);
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ColorUtils, SkColorToHSLGrey) {
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL hsl = {0, 0, 0};
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SkColorToHSL(SkColorSetARGB(255, 128, 128, 128), &hsl);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(hsl.h, 0);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(hsl.s, 0);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(hsl.l * 100),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<int>(0.5 * 100));  // Accurate to two decimal places.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ColorUtils, HSLToSkColorWithAlpha) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor red = SkColorSetARGB(128, 255, 0, 0);
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL hsl = {0, 1, 0.5};
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SkColor result = HSLToSkColor(hsl, 128);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetA(red), SkColorGetA(result));
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetR(red), SkColorGetR(result));
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetG(red), SkColorGetG(result));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetB(red), SkColorGetB(result));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ColorUtils, RGBtoHSLRoundTrip) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just spot check values near the edges.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int r = 0; r < 10; ++r) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int g = 0; g < 10; ++g) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int b = 0; b < 10; ++b) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkColor rgb = SkColorSetARGB(255, r, g, b);
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        HSL hsl = {0, 0, 0};
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        SkColorToHSL(rgb, &hsl);
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        SkColor out = HSLToSkColor(hsl, 255);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(SkColorGetR(out), SkColorGetR(rgb));
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(SkColorGetG(out), SkColorGetG(rgb));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(SkColorGetB(out), SkColorGetB(rgb));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int r = 240; r < 256; ++r) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int g = 240; g < 256; ++g) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int b = 240; b < 256; ++b) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkColor rgb = SkColorSetARGB(255, r, g, b);
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        HSL hsl = {0, 0, 0};
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        SkColorToHSL(rgb, &hsl);
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        SkColor out = HSLToSkColor(hsl, 255);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(SkColorGetR(out), SkColorGetR(rgb));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(SkColorGetG(out), SkColorGetG(rgb));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(SkColorGetB(out), SkColorGetB(rgb));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST(ColorUtils, IsWithinHSLRange) {
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL hsl = {0.3, 0.4, 0.5};
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL lower = {0.2, 0.3, 0.4};
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL upper = {0.4, 0.5, 0.6};
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Bounds are inclusive.
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.h = 0.2;
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.h = 0.4;
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.s = 0.3;
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.s = 0.5;
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.l = 0.4;
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.l = 0.6;
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST(ColorUtils, IsWithinHSLRangeHueWrapAround) {
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL hsl = {0.3, 0.4, 0.5};
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL lower = {0.8, -1, -1};
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL upper = {1.2, -1, -1};
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.h = 0.1;
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.h = 0.9;
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(IsWithinHSLRange(hsl, lower, upper));
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  hsl.h = 0.3;
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(IsWithinHSLRange(hsl, lower, upper));
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ColorUtils, ColorToHSLRegisterSpill) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In a opt build on Linux, this was causing a register spill on my laptop
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (Pentium M) when converting from SkColor to HSL.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor input = SkColorSetARGB(255, 206, 154, 89);
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  HSL hsl = {-1, -1, -1};
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SkColor result = HSLShift(input, hsl);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |result| should be the same as |input| since we passed in a value meaning
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no color shift.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetA(input), SkColorGetA(result));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetR(input), SkColorGetR(result));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetG(input), SkColorGetG(result));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SkColorGetB(input), SkColorGetB(result));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ColorUtils, AlphaBlend) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor fore = SkColorSetARGB(255, 200, 200, 200);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor back = SkColorSetARGB(255, 100, 100, 100);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(AlphaBlend(fore, back, 255) == fore);
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(AlphaBlend(fore, back, 0) == back);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One is fully transparent, result is partially transparent.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  back = SkColorSetA(back, 0);
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(136U, SkColorGetA(AlphaBlend(fore, back, 136)));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both are fully transparent, result is fully transparent.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fore = SkColorSetA(fore, 0);
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(0U, SkColorGetA(AlphaBlend(fore, back, 255)));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace color_utils
134