epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | |
| 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.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 8 | #include "Test.h" |
| 9 | #include "SkBlurMaskFilter.h" |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 10 | #include "SkCanvas.h" |
tomhudson@google.com | 889bd8b | 2011-09-27 17:38:17 +0000 | [diff] [blame] | 11 | #include "SkMath.h" |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 12 | #include "SkPaint.h" |
reed@google.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 13 | #include "SkRandom.h" |
| 14 | |
| 15 | /////////////////////////////////////////////////////////////////////////////// |
| 16 | |
| 17 | #define ILLEGAL_MODE ((SkXfermode::Mode)-1) |
| 18 | |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 19 | static const int outset = 100; |
| 20 | static const SkColor bgColor = SK_ColorWHITE; |
| 21 | static const int strokeWidth = 4; |
| 22 | |
| 23 | static void create(SkBitmap* bm, SkIRect bound, SkBitmap::Config config) { |
| 24 | bm->setConfig(config, bound.width(), bound.height()); |
| 25 | bm->allocPixels(); |
| 26 | } |
| 27 | |
| 28 | static void drawBG(SkCanvas* canvas) { |
| 29 | canvas->drawColor(bgColor); |
| 30 | } |
| 31 | |
| 32 | |
| 33 | struct 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. |
| 41 | static void draw50x50Rect(SkPath* path) { |
| 42 | path->addRect(0, 0, SkIntToScalar(50), SkIntToScalar(50)); |
| 43 | } |
| 44 | |
| 45 | //Tests |
| 46 | static 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 | */ |
| 62 | static 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.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 92 | static void test_blur(skiatest::Reporter* reporter) { |
reed@google.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 93 | |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 94 | SkPaint paint; |
| 95 | paint.setColor(SK_ColorGRAY); |
| 96 | paint.setStyle(SkPaint::kStroke_Style); |
| 97 | paint.setStrokeWidth(SkIntToScalar(strokeWidth)); |
reed@google.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 98 | |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 99 | 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.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 103 | |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 104 | 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.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 108 | |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 109 | SkMaskFilter::BlurInfo info; |
| 110 | sk_bzero(&info, sizeof(info)); |
| 111 | SkMaskFilter::BlurType type = filter->asABlur(&info); |
reed@google.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 112 | |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 113 | 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.com | 83a4446 | 2011-10-27 15:27:51 +0000 | [diff] [blame] | 124 | for (size_t test = 0; test < SK_ARRAY_COUNT(tests); ++test) { |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 125 | SkPath path; |
| 126 | tests[test].addPath(&path); |
bungeman@google.com | d16872c | 2011-09-02 15:46:17 +0000 | [diff] [blame] | 127 | SkPath strokedPath; |
| 128 | paint.getFillPath(path, &strokedPath); |
| 129 | SkRect refBound = strokedPath.getBounds(); |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 130 | SkIRect iref; |
| 131 | refBound.roundOut(&iref); |
bungeman@google.com | d16872c | 2011-09-02 15:46:17 +0000 | [diff] [blame] | 132 | iref.inset(-outset, -outset); |
bungeman@google.com | 5af16f8 | 2011-09-02 15:06:44 +0000 | [diff] [blame] | 133 | 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.com | 2b75f42 | 2011-07-07 13:43:38 +0000 | [diff] [blame] | 158 | } |
| 159 | } |
| 160 | |
| 161 | #include "TestClassDef.h" |
| 162 | DEFINE_TESTCLASS("BlurMaskFilter", BlurTestClass, test_blur) |