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