• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright 2015 Google Inc.
3   *
4   * Use of this source code is governed by a BSD-style license that can be
5   * found in the LICENSE file.
6   */
7  
8  #include "include/core/SkBitmap.h"
9  #include "include/core/SkCanvas.h"
10  #include "include/core/SkColor.h"
11  #include "include/core/SkColorFilter.h"
12  #include "include/core/SkPaint.h"
13  #include "include/core/SkRefCnt.h"
14  #include "tests/Test.h"
15  
16  #include <cmath>
17  #include <cstdlib>
18  
assert_color(skiatest::Reporter * reporter,SkColor expected,SkColor actual,int tolerance)19  static inline void assert_color(skiatest::Reporter* reporter,
20                                  SkColor expected, SkColor actual, int tolerance) {
21      REPORTER_ASSERT(reporter, abs((int)(SkColorGetA(expected) - SkColorGetA(actual))) <= tolerance);
22      REPORTER_ASSERT(reporter, abs((int)(SkColorGetR(expected) - SkColorGetR(actual))) <= tolerance);
23      REPORTER_ASSERT(reporter, abs((int)(SkColorGetG(expected) - SkColorGetG(actual))) <= tolerance);
24      REPORTER_ASSERT(reporter, abs((int)(SkColorGetB(expected) - SkColorGetB(actual))) <= tolerance);
25  }
26  
assert_color(skiatest::Reporter * reporter,SkColor expected,SkColor actual)27  static inline void assert_color(skiatest::Reporter* reporter, SkColor expected, SkColor actual) {
28      const int TOLERANCE = 1;
29      assert_color(reporter, expected, actual, TOLERANCE);
30  }
31  
32  /**
33   * This test case is a mirror of the Android CTS tests for MatrixColorFilter
34   * found in the android.graphics.ColorMatrixColorFilterTest class.
35   */
test_colorMatrixCTS(skiatest::Reporter * reporter)36  static inline void test_colorMatrixCTS(skiatest::Reporter* reporter) {
37  
38      SkBitmap bitmap;
39      bitmap.allocN32Pixels(1,1);
40  
41      SkCanvas canvas(bitmap);
42      SkPaint paint;
43  
44      float blueToCyan[20] = {
45              1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
46              0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
47              0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
48              0.0f, 0.0f, 0.0f, 1.0f, 0.0f };
49      paint.setColorFilter(SkColorFilters::Matrix(blueToCyan));
50  
51      paint.setColor(SK_ColorBLUE);
52      canvas.drawPoint(0, 0, paint);
53      assert_color(reporter, SK_ColorCYAN, bitmap.getColor(0, 0));
54  
55      paint.setColor(SK_ColorGREEN);
56      canvas.drawPoint(0, 0, paint);
57      assert_color(reporter, SK_ColorGREEN, bitmap.getColor(0, 0));
58  
59      paint.setColor(SK_ColorRED);
60      canvas.drawPoint(0, 0, paint);
61      assert_color(reporter, SK_ColorRED, bitmap.getColor(0, 0));
62  
63      // color components are clipped, not scaled
64      paint.setColor(SK_ColorMAGENTA);
65      canvas.drawPoint(0, 0, paint);
66      assert_color(reporter, SK_ColorWHITE, bitmap.getColor(0, 0));
67  
68      float transparentRedAddBlue[20] = {
69              1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
70              0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
71              0.0f, 0.0f, 1.0f, 0.0f, 64.0f/255,
72             -0.5f, 0.0f, 0.0f, 1.0f, 0.0f
73      };
74      paint.setColorFilter(SkColorFilters::Matrix(transparentRedAddBlue));
75      bitmap.eraseColor(SK_ColorTRANSPARENT);
76  
77      paint.setColor(SK_ColorRED);
78      canvas.drawPoint(0, 0, paint);
79      assert_color(reporter, SkColorSetARGB(128, 255, 0, 64), bitmap.getColor(0, 0), 2);
80  
81      paint.setColor(SK_ColorCYAN);
82      canvas.drawPoint(0, 0, paint);
83      // blue gets clipped
84      assert_color(reporter, SK_ColorCYAN, bitmap.getColor(0, 0));
85  
86      // change array to filter out green
87      REPORTER_ASSERT(reporter, 1.0f == transparentRedAddBlue[6]);
88      transparentRedAddBlue[6] = 0.0f;
89  
90      // check that changing the array has no effect
91      canvas.drawPoint(0, 0, paint);
92      assert_color(reporter, SK_ColorCYAN, bitmap.getColor(0, 0));
93  
94      // create a new filter with the changed matrix
95      paint.setColorFilter(SkColorFilters::Matrix(transparentRedAddBlue));
96      canvas.drawPoint(0, 0, paint);
97      assert_color(reporter, SK_ColorBLUE, bitmap.getColor(0, 0));
98  }
99  
DEF_TEST(ColorMatrix,reporter)100  DEF_TEST(ColorMatrix, reporter) {
101      test_colorMatrixCTS(reporter);
102  }
103  
104  
DEF_TEST(ColorMatrix_clamp_while_unpremul,r)105  DEF_TEST(ColorMatrix_clamp_while_unpremul, r) {
106      // This matrix does green += 255/255 and alpha += 32/255.  We want to test
107      // that if we pass it opaque alpha and small red and blue values, red and
108      // blue stay unchanged, not pumped up by that ~1.12 intermediate alpha.
109      float m[] = {
110          1, 0, 0, 0, 0,
111          0, 1, 0, 0, 1,
112          0, 0, 1, 0, 0,
113          0, 0, 0, 1, 32.0f/255,
114      };
115      auto filter = SkColorFilters::Matrix(m);
116  
117      SkColor filtered = filter->filterColor(0xff0a0b0c);
118      REPORTER_ASSERT(r, SkColorGetA(filtered) == 0xff);
119      REPORTER_ASSERT(r, SkColorGetR(filtered) == 0x0a);
120      REPORTER_ASSERT(r, SkColorGetG(filtered) == 0xff);
121      REPORTER_ASSERT(r, SkColorGetB(filtered) == 0x0c);
122  }
123