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 */ 8#include "Test.h" 9#include "SkBlurMaskFilter.h" 10#include "SkCanvas.h" 11#include "SkMath.h" 12#include "SkPaint.h" 13#include "SkRandom.h" 14 15/////////////////////////////////////////////////////////////////////////////// 16 17#define ILLEGAL_MODE ((SkXfermode::Mode)-1) 18 19static 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 92static void test_blur(skiatest::Reporter* reporter) { 93 94 SkPaint paint; 95 paint.setColor(SK_ColorGRAY); 96 paint.setStyle(SkPaint::kStroke_Style); 97 paint.setStrokeWidth(SkIntToScalar(strokeWidth)); 98 99 SkScalar radius = SkIntToScalar(5); 100 for (int style = 0; style < SkBlurMaskFilter::kBlurStyleCount; ++style) { 101 SkBlurMaskFilter::BlurStyle blurStyle = 102 static_cast<SkBlurMaskFilter::BlurStyle>(style); 103 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); 108 109 SkMaskFilter::BlurInfo info; 110 sk_bzero(&info, sizeof(info)); 111 SkMaskFilter::BlurType type = filter->asABlur(&info); 112 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 124 for (size_t test = 0; test < SK_ARRAY_COUNT(tests); ++test) { 125 SkPath path; 126 tests[test].addPath(&path); 127 SkPath strokedPath; 128 paint.getFillPath(path, &strokedPath); 129 SkRect refBound = strokedPath.getBounds(); 130 SkIRect iref; 131 refBound.roundOut(&iref); 132 iref.inset(-outset, -outset); 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 } 158 } 159} 160 161#include "TestClassDef.h" 162DEFINE_TESTCLASS("BlurMaskFilter", BlurTestClass, test_blur) 163