blob: c0d16f8f3f1e5d4618b241048fd24061b3ed77b2 [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#include "SkRandom.h"
14
15///////////////////////////////////////////////////////////////////////////////
16
17#define ILLEGAL_MODE ((SkXfermode::Mode)-1)
18
bungeman@google.com5af16f82011-09-02 15:06:44 +000019static const int outset = 100;
20static const SkColor bgColor = SK_ColorWHITE;
21static const int strokeWidth = 4;
22
23static void create(SkBitmap* bm, SkIRect bound, SkBitmap::Config config) {
24 bm->setConfig(config, bound.width(), bound.height());
25 bm->allocPixels();
26}
27
28static void drawBG(SkCanvas* canvas) {
29 canvas->drawColor(bgColor);
30}
31
32
33struct BlurTest {
34 void (*addPath)(SkPath*);
35 int viewLen;
36 SkIRect views[9];
37};
38
39//Path Draw Procs
40//Beware that paths themselves my draw differently depending on the clip.
41static void draw50x50Rect(SkPath* path) {
42 path->addRect(0, 0, SkIntToScalar(50), SkIntToScalar(50));
43}
44
45//Tests
46static BlurTest tests[] = {
47 { draw50x50Rect, 3, {
48 //inner half of blur
49 { 0, 0, 50, 50 },
50 //blur, but no path.
51 { 50 + strokeWidth/2, 50 + strokeWidth/2, 100, 100 },
52 //just an edge
53 { 40, strokeWidth, 60, 50 - strokeWidth },
54 }},
55};
56
57/** Assumes that the ref draw was completely inside ref canvas --
58 implies that everything outside is "bgColor".
59 Checks that all overlap is the same and that all non-overlap on the
60 ref is "bgColor".
61 */
62static bool compare(const SkBitmap& ref, const SkIRect& iref,
63 const SkBitmap& test, const SkIRect& itest)
64{
65 const int xOff = itest.fLeft - iref.fLeft;
66 const int yOff = itest.fTop - iref.fTop;
67
68 SkAutoLockPixels alpRef(ref);
69 SkAutoLockPixels alpTest(test);
70
71 for (int y = 0; y < test.height(); ++y) {
72 for (int x = 0; x < test.width(); ++x) {
73 SkColor testColor = test.getColor(x, y);
74 int refX = x + xOff;
75 int refY = y + yOff;
76 SkColor refColor;
77 if (refX >= 0 && refX < ref.width() &&
78 refY >= 0 && refY < ref.height())
79 {
80 refColor = ref.getColor(refX, refY);
81 } else {
82 refColor = bgColor;
83 }
84 if (refColor != testColor) {
85 return false;
86 }
87 }
88 }
89 return true;
90}
91
reed@google.com2b75f422011-07-07 13:43:38 +000092static void test_blur(skiatest::Reporter* reporter) {
reed@google.com2b75f422011-07-07 13:43:38 +000093
bungeman@google.com5af16f82011-09-02 15:06:44 +000094 SkPaint paint;
95 paint.setColor(SK_ColorGRAY);
96 paint.setStyle(SkPaint::kStroke_Style);
97 paint.setStrokeWidth(SkIntToScalar(strokeWidth));
reed@google.com2b75f422011-07-07 13:43:38 +000098
bungeman@google.com5af16f82011-09-02 15:06:44 +000099 SkScalar radius = SkIntToScalar(5);
100 for (int style = 0; style < SkBlurMaskFilter::kBlurStyleCount; ++style) {
101 SkBlurMaskFilter::BlurStyle blurStyle =
102 static_cast<SkBlurMaskFilter::BlurStyle>(style);
reed@google.com2b75f422011-07-07 13:43:38 +0000103
bungeman@google.com5af16f82011-09-02 15:06:44 +0000104 const uint32_t flagPermutations = SkBlurMaskFilter::kAll_BlurFlag;
105 for (uint32_t flags = 0; flags < flagPermutations; ++flags) {
106 SkMaskFilter* filter;
107 filter = SkBlurMaskFilter::Create(radius, blurStyle, flags);
reed@google.com2b75f422011-07-07 13:43:38 +0000108
bungeman@google.com5af16f82011-09-02 15:06:44 +0000109 SkMaskFilter::BlurInfo info;
110 sk_bzero(&info, sizeof(info));
111 SkMaskFilter::BlurType type = filter->asABlur(&info);
reed@google.com2b75f422011-07-07 13:43:38 +0000112
bungeman@google.com5af16f82011-09-02 15:06:44 +0000113 REPORTER_ASSERT(reporter, type ==
114 static_cast<SkMaskFilter::BlurType>(style + 1));
115 REPORTER_ASSERT(reporter, info.fRadius == radius);
116 REPORTER_ASSERT(reporter, info.fIgnoreTransform ==
117 SkToBool(flags & SkBlurMaskFilter::kIgnoreTransform_BlurFlag));
118 REPORTER_ASSERT(reporter, info.fHighQuality ==
119 SkToBool(flags & SkBlurMaskFilter::kHighQuality_BlurFlag));
120
121 paint.setMaskFilter(filter);
122 filter->unref();
123
tomhudson@google.com83a44462011-10-27 15:27:51 +0000124 for (size_t test = 0; test < SK_ARRAY_COUNT(tests); ++test) {
bungeman@google.com5af16f82011-09-02 15:06:44 +0000125 SkPath path;
126 tests[test].addPath(&path);
bungeman@google.comd16872c2011-09-02 15:46:17 +0000127 SkPath strokedPath;
128 paint.getFillPath(path, &strokedPath);
129 SkRect refBound = strokedPath.getBounds();
bungeman@google.com5af16f82011-09-02 15:06:44 +0000130 SkIRect iref;
131 refBound.roundOut(&iref);
bungeman@google.comd16872c2011-09-02 15:46:17 +0000132 iref.inset(-outset, -outset);
bungeman@google.com5af16f82011-09-02 15:06:44 +0000133 SkBitmap refBitmap;
134 create(&refBitmap, iref, SkBitmap::kARGB_8888_Config);
135
136 SkCanvas refCanvas(refBitmap);
137 refCanvas.translate(SkIntToScalar(-iref.fLeft),
138 SkIntToScalar(-iref.fTop));
139 drawBG(&refCanvas);
140 refCanvas.drawPath(path, paint);
141
142 for (int view = 0; view < tests[test].viewLen; ++view) {
143 SkIRect itest = tests[test].views[view];
144 SkBitmap testBitmap;
145 create(&testBitmap, itest, SkBitmap::kARGB_8888_Config);
146
147 SkCanvas testCanvas(testBitmap);
148 testCanvas.translate(SkIntToScalar(-itest.fLeft),
149 SkIntToScalar(-itest.fTop));
150 drawBG(&testCanvas);
151 testCanvas.drawPath(path, paint);
152
153 REPORTER_ASSERT(reporter,
154 compare(refBitmap, iref, testBitmap, itest));
155 }
156 }
157 }
reed@google.com2b75f422011-07-07 13:43:38 +0000158 }
159}
160
161#include "TestClassDef.h"
162DEFINE_TESTCLASS("BlurMaskFilter", BlurTestClass, test_blur)