blob: 57dc940a6d817a53b29dc4e60b86c4f82dc0150d [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@google.com2b75f422011-07-07 13:43:38 +00008#include "Test.h"
9#include "SkBlurMaskFilter.h"
bungeman@google.com5af16f82011-09-02 15:06:44 +000010#include "SkCanvas.h"
tomhudson@google.com889bd8b2011-09-27 17:38:17 +000011#include "SkMath.h"
bungeman@google.com5af16f82011-09-02 15:06:44 +000012#include "SkPaint.h"
reed@google.com2b75f422011-07-07 13:43:38 +000013
14///////////////////////////////////////////////////////////////////////////////
15
16#define ILLEGAL_MODE ((SkXfermode::Mode)-1)
17
bungeman@google.com5af16f82011-09-02 15:06:44 +000018static const int outset = 100;
19static const SkColor bgColor = SK_ColorWHITE;
20static const int strokeWidth = 4;
21
22static void create(SkBitmap* bm, SkIRect bound, SkBitmap::Config config) {
23 bm->setConfig(config, bound.width(), bound.height());
24 bm->allocPixels();
25}
26
27static void drawBG(SkCanvas* canvas) {
28 canvas->drawColor(bgColor);
29}
30
31
32struct BlurTest {
33 void (*addPath)(SkPath*);
34 int viewLen;
35 SkIRect views[9];
36};
37
38//Path Draw Procs
39//Beware that paths themselves my draw differently depending on the clip.
40static void draw50x50Rect(SkPath* path) {
41 path->addRect(0, 0, SkIntToScalar(50), SkIntToScalar(50));
42}
43
44//Tests
45static BlurTest tests[] = {
46 { draw50x50Rect, 3, {
47 //inner half of blur
48 { 0, 0, 50, 50 },
49 //blur, but no path.
50 { 50 + strokeWidth/2, 50 + strokeWidth/2, 100, 100 },
51 //just an edge
52 { 40, strokeWidth, 60, 50 - strokeWidth },
53 }},
54};
55
56/** Assumes that the ref draw was completely inside ref canvas --
57 implies that everything outside is "bgColor".
58 Checks that all overlap is the same and that all non-overlap on the
59 ref is "bgColor".
60 */
61static bool compare(const SkBitmap& ref, const SkIRect& iref,
62 const SkBitmap& test, const SkIRect& itest)
63{
64 const int xOff = itest.fLeft - iref.fLeft;
65 const int yOff = itest.fTop - iref.fTop;
66
67 SkAutoLockPixels alpRef(ref);
68 SkAutoLockPixels alpTest(test);
69
70 for (int y = 0; y < test.height(); ++y) {
71 for (int x = 0; x < test.width(); ++x) {
72 SkColor testColor = test.getColor(x, y);
73 int refX = x + xOff;
74 int refY = y + yOff;
75 SkColor refColor;
76 if (refX >= 0 && refX < ref.width() &&
77 refY >= 0 && refY < ref.height())
78 {
79 refColor = ref.getColor(refX, refY);
80 } else {
81 refColor = bgColor;
82 }
83 if (refColor != testColor) {
84 return false;
85 }
86 }
87 }
88 return true;
89}
90
reed@google.com2b75f422011-07-07 13:43:38 +000091static void test_blur(skiatest::Reporter* reporter) {
reed@google.com2b75f422011-07-07 13:43:38 +000092
bungeman@google.com5af16f82011-09-02 15:06:44 +000093 SkPaint paint;
94 paint.setColor(SK_ColorGRAY);
95 paint.setStyle(SkPaint::kStroke_Style);
96 paint.setStrokeWidth(SkIntToScalar(strokeWidth));
reed@google.com2b75f422011-07-07 13:43:38 +000097
bungeman@google.com5af16f82011-09-02 15:06:44 +000098 SkScalar radius = SkIntToScalar(5);
99 for (int style = 0; style < SkBlurMaskFilter::kBlurStyleCount; ++style) {
100 SkBlurMaskFilter::BlurStyle blurStyle =
101 static_cast<SkBlurMaskFilter::BlurStyle>(style);
reed@google.com2b75f422011-07-07 13:43:38 +0000102
bungeman@google.com5af16f82011-09-02 15:06:44 +0000103 const uint32_t flagPermutations = SkBlurMaskFilter::kAll_BlurFlag;
104 for (uint32_t flags = 0; flags < flagPermutations; ++flags) {
105 SkMaskFilter* filter;
106 filter = SkBlurMaskFilter::Create(radius, blurStyle, flags);
reed@google.com2b75f422011-07-07 13:43:38 +0000107
bungeman@google.com5af16f82011-09-02 15:06:44 +0000108 SkMaskFilter::BlurInfo info;
109 sk_bzero(&info, sizeof(info));
110 SkMaskFilter::BlurType type = filter->asABlur(&info);
reed@google.com2b75f422011-07-07 13:43:38 +0000111
bungeman@google.com5af16f82011-09-02 15:06:44 +0000112 REPORTER_ASSERT(reporter, type ==
113 static_cast<SkMaskFilter::BlurType>(style + 1));
114 REPORTER_ASSERT(reporter, info.fRadius == radius);
115 REPORTER_ASSERT(reporter, info.fIgnoreTransform ==
116 SkToBool(flags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag));
117 REPORTER_ASSERT(reporter, info.fHighQuality ==
118 SkToBool(flags & SkBlurMaskFilter::kHighQuality_BlurFlag));
119
120 paint.setMaskFilter(filter);
121 filter->unref();
122
tomhudson@google.com83a44462011-10-27 15:27:51 +0000123 for (size_t test = 0; test < SK_ARRAY_COUNT(tests); ++test) {
bungeman@google.com5af16f82011-09-02 15:06:44 +0000124 SkPath path;
125 tests[test].addPath(&path);
bungeman@google.comd16872c2011-09-02 15:46:17 +0000126 SkPath strokedPath;
127 paint.getFillPath(path, &strokedPath);
128 SkRect refBound = strokedPath.getBounds();
bungeman@google.com5af16f82011-09-02 15:06:44 +0000129 SkIRect iref;
130 refBound.roundOut(&iref);
bungeman@google.comd16872c2011-09-02 15:46:17 +0000131 iref.inset(-outset, -outset);
bungeman@google.com5af16f82011-09-02 15:06:44 +0000132 SkBitmap refBitmap;
133 create(&refBitmap, iref, SkBitmap::kARGB_8888_Config);
134
135 SkCanvas refCanvas(refBitmap);
136 refCanvas.translate(SkIntToScalar(-iref.fLeft),
137 SkIntToScalar(-iref.fTop));
138 drawBG(&refCanvas);
139 refCanvas.drawPath(path, paint);
140
141 for (int view = 0; view < tests[test].viewLen; ++view) {
142 SkIRect itest = tests[test].views[view];
143 SkBitmap testBitmap;
144 create(&testBitmap, itest, SkBitmap::kARGB_8888_Config);
145
146 SkCanvas testCanvas(testBitmap);
147 testCanvas.translate(SkIntToScalar(-itest.fLeft),
148 SkIntToScalar(-itest.fTop));
149 drawBG(&testCanvas);
150 testCanvas.drawPath(path, paint);
151
152 REPORTER_ASSERT(reporter,
153 compare(refBitmap, iref, testBitmap, itest));
154 }
155 }
156 }
reed@google.com2b75f422011-07-07 13:43:38 +0000157 }
158}
159
160#include "TestClassDef.h"
161DEFINE_TESTCLASS("BlurMaskFilter", BlurTestClass, test_blur)