|  | /* | 
|  | * 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); | 
|  | } |