1 /*
2  * Copyright 2016 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 "SkBitmap.h"
9 #include "SkCanvas.h"
10 #include "SkGradientShader.h"
11 #include "SkPaintImageFilter.h"
12 #include "SkShader.h"
13 #include "Test.h"
14 
15 static void test_unscaled(skiatest::Reporter* reporter) {
16     int w = 10, h = 10;
17     SkRect r = SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h));
18 
19     SkBitmap filterResult, paintResult;
20 
21     filterResult.allocN32Pixels(w, h);
22     SkCanvas canvasFilter(filterResult);
23     canvasFilter.clear(0x00000000);
24 
25     paintResult.allocN32Pixels(w, h);
26     SkCanvas canvasPaint(paintResult);
27     canvasPaint.clear(0x00000000);
28 
29     SkPoint center = SkPoint::Make(SkIntToScalar(5), SkIntToScalar(5));
30     SkColor colors[] = {SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN};
31     SkScalar pos[] = {0, SK_ScalarHalf, SK_Scalar1};
32     SkScalar radius = SkIntToScalar(5);
33 
34     SkPaint gradientPaint;
35     gradientPaint.setShader(SkGradientShader::MakeRadial(
36         center, radius, colors, pos, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
37 
38     // Test using the image filter
39     {
40         SkPaint paint;
41         SkImageFilter::CropRect cr(r);
42         paint.setImageFilter(SkPaintImageFilter::Make(gradientPaint, &cr));
43         canvasFilter.drawRect(r, paint);
44     }
45 
46     // Test using the paint directly
47     {
48         canvasPaint.drawRect(r, gradientPaint);
49     }
50 
51     // Assert that both paths yielded the same result
52     for (int y = 0; y < r.height(); ++y) {
53         const SkPMColor* filterPtr = filterResult.getAddr32(0, y);
54         const SkPMColor* paintPtr = paintResult.getAddr32(0, y);
55         for (int x = 0; x < r.width(); ++x, ++filterPtr, ++paintPtr) {
56             REPORTER_ASSERT(reporter, *filterPtr == *paintPtr);
57         }
58     }
59 }
60 
61 static void test_scaled(skiatest::Reporter* reporter) {
62     int w = 10, h = 10;
63     SkRect r = SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h));
64 
65     SkBitmap filterResult, paintResult;
66 
67     filterResult.allocN32Pixels(w, h);
68     SkCanvas canvasFilter(filterResult);
69     canvasFilter.clear(0x00000000);
70 
71     paintResult.allocN32Pixels(w, h);
72     SkCanvas canvasPaint(paintResult);
73     canvasPaint.clear(0x00000000);
74 
75     SkPoint center = SkPoint::Make(SkIntToScalar(5), SkIntToScalar(5));
76     SkColor colors[] = {SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN};
77     SkScalar pos[] = {0, SK_ScalarHalf, SK_Scalar1};
78     SkScalar radius = SkIntToScalar(5);
79 
80     SkPaint gradientPaint;
81     gradientPaint.setShader(SkGradientShader::MakeRadial(
82         center, radius, colors, pos, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
83 
84     // Test using the image filter
85     {
86         SkPaint paint;
87         SkImageFilter::CropRect cr(r);
88         paint.setImageFilter(SkPaintImageFilter::Make(gradientPaint, &cr));
89         canvasFilter.scale(SkIntToScalar(2), SkIntToScalar(2));
90         canvasFilter.drawRect(r, paint);
91     }
92 
93     // Test using the paint directly
94     {
95         canvasPaint.scale(SkIntToScalar(2), SkIntToScalar(2));
96         canvasPaint.drawRect(r, gradientPaint);
97     }
98 
99     // Assert that both paths yielded the same result
100     for (int y = 0; y < r.height(); ++y) {
101         const SkPMColor* filterPtr = filterResult.getAddr32(0, y);
102         const SkPMColor* paintPtr = paintResult.getAddr32(0, y);
103         for (int x = 0; x < r.width(); ++x, ++filterPtr, ++paintPtr) {
104             REPORTER_ASSERT(reporter, *filterPtr == *paintPtr);
105         }
106     }
107 }
108 
109 DEF_TEST(PaintImageFilter, reporter) {
110     test_unscaled(reporter);
111     test_scaled(reporter);
112 }
113