| /* | 
 |  * Copyright 2015 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "include/core/SkBitmap.h" | 
 | #include "include/core/SkCanvas.h" | 
 | #include "include/core/SkColor.h" | 
 | #include "include/core/SkColorFilter.h" | 
 | #include "include/core/SkPaint.h" | 
 | #include "include/core/SkRefCnt.h" | 
 | #include "tests/Test.h" | 
 |  | 
 | #include <cmath> | 
 |  | 
 | static inline void assert_color(skiatest::Reporter* reporter, | 
 |                                 SkColor expected, SkColor actual, int tolerance) { | 
 |     REPORTER_ASSERT(reporter, abs((int)(SkColorGetA(expected) - SkColorGetA(actual))) <= tolerance); | 
 |     REPORTER_ASSERT(reporter, abs((int)(SkColorGetR(expected) - SkColorGetR(actual))) <= tolerance); | 
 |     REPORTER_ASSERT(reporter, abs((int)(SkColorGetG(expected) - SkColorGetG(actual))) <= tolerance); | 
 |     REPORTER_ASSERT(reporter, abs((int)(SkColorGetB(expected) - SkColorGetB(actual))) <= tolerance); | 
 | } | 
 |  | 
 | static inline void assert_color(skiatest::Reporter* reporter, SkColor expected, SkColor actual) { | 
 |     const int TOLERANCE = 1; | 
 |     assert_color(reporter, expected, actual, TOLERANCE); | 
 | } | 
 |  | 
 | /** | 
 |  * This test case is a mirror of the Android CTS tests for MatrixColorFilter | 
 |  * found in the android.graphics.ColorMatrixColorFilterTest class. | 
 |  */ | 
 | static inline void test_colorMatrixCTS(skiatest::Reporter* reporter) { | 
 |  | 
 |     SkBitmap bitmap; | 
 |     bitmap.allocN32Pixels(1,1); | 
 |  | 
 |     SkCanvas canvas(bitmap); | 
 |     SkPaint paint; | 
 |  | 
 |     float blueToCyan[20] = { | 
 |             1.0f, 0.0f, 0.0f, 0.0f, 0.0f, | 
 |             0.0f, 1.0f, 1.0f, 0.0f, 0.0f, | 
 |             0.0f, 0.0f, 1.0f, 0.0f, 0.0f, | 
 |             0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; | 
 |     paint.setColorFilter(SkColorFilters::Matrix(blueToCyan)); | 
 |  | 
 |     paint.setColor(SK_ColorBLUE); | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     assert_color(reporter, SK_ColorCYAN, bitmap.getColor(0, 0)); | 
 |  | 
 |     paint.setColor(SK_ColorGREEN); | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     assert_color(reporter, SK_ColorGREEN, bitmap.getColor(0, 0)); | 
 |  | 
 |     paint.setColor(SK_ColorRED); | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     assert_color(reporter, SK_ColorRED, bitmap.getColor(0, 0)); | 
 |  | 
 |     // color components are clipped, not scaled | 
 |     paint.setColor(SK_ColorMAGENTA); | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     assert_color(reporter, SK_ColorWHITE, bitmap.getColor(0, 0)); | 
 |  | 
 |     float transparentRedAddBlue[20] = { | 
 |             1.0f, 0.0f, 0.0f, 0.0f, 0.0f, | 
 |             0.0f, 1.0f, 0.0f, 0.0f, 0.0f, | 
 |             0.0f, 0.0f, 1.0f, 0.0f, 64.0f/255, | 
 |            -0.5f, 0.0f, 0.0f, 1.0f, 0.0f | 
 |     }; | 
 |     paint.setColorFilter(SkColorFilters::Matrix(transparentRedAddBlue)); | 
 |     bitmap.eraseColor(SK_ColorTRANSPARENT); | 
 |  | 
 |     paint.setColor(SK_ColorRED); | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     assert_color(reporter, SkColorSetARGB(128, 255, 0, 64), bitmap.getColor(0, 0), 2); | 
 |  | 
 |     paint.setColor(SK_ColorCYAN); | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     // blue gets clipped | 
 |     assert_color(reporter, SK_ColorCYAN, bitmap.getColor(0, 0)); | 
 |  | 
 |     // change array to filter out green | 
 |     REPORTER_ASSERT(reporter, 1.0f == transparentRedAddBlue[6]); | 
 |     transparentRedAddBlue[6] = 0.0f; | 
 |  | 
 |     // check that changing the array has no effect | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     assert_color(reporter, SK_ColorCYAN, bitmap.getColor(0, 0)); | 
 |  | 
 |     // create a new filter with the changed matrix | 
 |     paint.setColorFilter(SkColorFilters::Matrix(transparentRedAddBlue)); | 
 |     canvas.drawPoint(0, 0, paint); | 
 |     assert_color(reporter, SK_ColorBLUE, bitmap.getColor(0, 0)); | 
 | } | 
 |  | 
 | DEF_TEST(ColorMatrix, reporter) { | 
 |     test_colorMatrixCTS(reporter); | 
 | } | 
 |  | 
 |  | 
 | DEF_TEST(ColorMatrix_clamp_while_unpremul, r) { | 
 |     // This matrix does green += 255/255 and alpha += 32/255.  We want to test | 
 |     // that if we pass it opaque alpha and small red and blue values, red and | 
 |     // blue stay unchanged, not pumped up by that ~1.12 intermediate alpha. | 
 |     float m[] = { | 
 |         1, 0, 0, 0, 0, | 
 |         0, 1, 0, 0, 1, | 
 |         0, 0, 1, 0, 0, | 
 |         0, 0, 0, 1, 32.0f/255, | 
 |     }; | 
 |     auto filter = SkColorFilters::Matrix(m); | 
 |  | 
 |     SkColor4f srcColor = SkColor4f::FromColor(0xff0a0b0c); | 
 |     SkColor filtered = filter->filterColor4f(srcColor, nullptr, nullptr).toSkColor(); | 
 |     REPORTER_ASSERT(r, SkColorGetA(filtered) == 0xff); | 
 |     REPORTER_ASSERT(r, SkColorGetR(filtered) == 0x0a); | 
 |     REPORTER_ASSERT(r, SkColorGetG(filtered) == 0xff); | 
 |     REPORTER_ASSERT(r, SkColorGetB(filtered) == 0x0c); | 
 | } |