• 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