1 /* 2 * Copyright 2013 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 "Test.h" 9 #include "TestClassDef.h" 10 #include "SkDeviceLooper.h" 11 #include "SkRasterClip.h" 12 13 static void make_bm(SkBitmap* bm, int w, int h) { 14 bm->setConfig(SkBitmap::kA8_Config, w, h); 15 bm->allocPixels(); 16 } 17 18 static bool equal(const SkRasterClip& a, const SkRasterClip& b) { 19 if (a.isBW()) { 20 return b.isBW() && a.bwRgn() == b.bwRgn(); 21 } else { 22 return a.isAA() && a.aaRgn() == b.aaRgn(); 23 } 24 } 25 26 static const struct { 27 SkISize fDevSize; 28 SkIRect fRCBounds; 29 SkIRect fRect; 30 } gRec[] = { 31 { { 4000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 4000, 4000 } }, 32 { { 10, 4000 }, { 0, 0, 10, 4000 }, { 0, 0, 4000, 4000 } }, 33 // very large devce, small rect 34 { { 32000, 10 }, { 0, 0, 32000, 10 }, { 0, 0, 4000, 4000 } }, 35 { { 10, 32000 }, { 0, 0, 10, 32000 }, { 0, 0, 4000, 4000 } }, 36 // very large device, small clip 37 { { 32000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 32000, 32000 } }, 38 { { 10, 32000 }, { 0, 0, 10, 4000 }, { 0, 0, 32000, 32000 } }, 39 }; 40 41 static void test_simple(skiatest::Reporter* reporter) { 42 43 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { 44 SkBitmap bitmap; 45 make_bm(&bitmap, gRec[i].fDevSize.width(), gRec[i].fDevSize.height()); 46 47 SkRasterClip rc(gRec[i].fRCBounds); 48 49 for (int aa = 0; aa <= 1; ++aa) { 50 SkDeviceLooper looper(bitmap, rc, gRec[i].fRect, SkToBool(aa)); 51 52 bool valid = looper.next(); 53 REPORTER_ASSERT(reporter, valid); 54 if (valid) { 55 REPORTER_ASSERT(reporter, looper.getBitmap().width() == bitmap.width()); 56 REPORTER_ASSERT(reporter, looper.getBitmap().height() == bitmap.height()); 57 REPORTER_ASSERT(reporter, equal(looper.getRC(), rc)); 58 59 REPORTER_ASSERT(reporter, !looper.next()); 60 } 61 } 62 // test that a rect that doesn't intersect returns no loops 63 { 64 SkIRect r = rc.getBounds(); 65 r.offset(r.width(), 0); 66 SkDeviceLooper looper(bitmap, rc, r, false); 67 REPORTER_ASSERT(reporter, !looper.next()); 68 } 69 } 70 } 71 72 // mask-bits are interpreted as the areas where the clip is visible 73 // [ 0x01 0x02 ] 74 // [ 0x04 0x08 ] 75 // 76 static void make_rgn(SkRegion* rgn, int w, int h, unsigned mask) { 77 SkASSERT(SkAlign2(w)); 78 SkASSERT(SkAlign2(h)); 79 w >>= 1; 80 h >>= 1; 81 const SkIRect baseR = SkIRect::MakeWH(w, h); 82 83 int bit = 1; 84 for (int y = 0; y <= 1; ++y) { 85 for (int x = 0; x <= 1; ++x) { 86 if (mask & bit) { 87 SkIRect r = baseR; 88 r.offset(x * w, y * h); 89 rgn->op(r, SkRegion::kUnion_Op); 90 } 91 bit <<= 1; 92 } 93 } 94 } 95 96 static void test_complex(skiatest::Reporter* reporter) { 97 // choose size values that will result in 4 quadrants, given fAA setting 98 const int BW_SIZE = 17 * 1000; 99 const int AA_SIZE = 7 * 1000; 100 101 struct { 102 SkISize fSize; 103 bool fAA; 104 } const gRec[] = { 105 { { BW_SIZE, BW_SIZE }, false }, 106 { { AA_SIZE, AA_SIZE }, true }, 107 }; 108 109 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { 110 const int w = gRec[i].fSize.width(); 111 const int h = gRec[i].fSize.height(); 112 113 SkBitmap bitmap; 114 make_bm(&bitmap, w, h); 115 116 const SkIRect rect = SkIRect::MakeWH(w, h); 117 118 // mask-bits are interpreted as the areas where the clip is visible 119 // [ 0x01 0x02 ] 120 // [ 0x04 0x08 ] 121 // 122 for (int mask = 0; mask <= 15; ++mask) { 123 SkRegion rgn; 124 make_rgn(&rgn, w, h, mask); 125 126 SkRasterClip rc; 127 rc.op(rgn, SkRegion::kReplace_Op); 128 129 SkDeviceLooper looper(bitmap, rc, rect, gRec[i].fAA); 130 while (looper.next()) { 131 REPORTER_ASSERT(reporter, !looper.getRC().isEmpty()); 132 } 133 } 134 } 135 } 136 137 DEF_TEST(DeviceLooper, reporter) { 138 test_simple(reporter); 139 test_complex(reporter); 140 } 141