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