| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "gm.h" | 8 #include "gm.h" |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkPath.h" | 10 #include "SkPath.h" |
| 11 | 11 |
| 12 static void test_quadstroke(SkCanvas* canvas) { | |
| 13 SkPath path; | |
| 14 path.moveTo(6, 0); | |
| 15 path.quadTo(150, 150, 0, 6); | |
| 16 | |
| 17 SkPaint paint; | |
| 18 | |
| 19 paint.setAntiAlias(true); | |
| 20 paint.setStyle(SkPaint::kStroke_Style); | |
| 21 canvas->translate(20, 20); | |
| 22 | |
| 23 #if 1 | |
| 24 canvas->drawPath(path, paint); | |
| 25 canvas->translate(100, 0); | |
| 26 #endif | |
| 27 | |
| 28 paint.setStrokeWidth(1.01f); | |
| 29 canvas->drawPath(path, paint); | |
| 30 } | |
| 31 | |
| 32 static void draw_conic(SkCanvas* canvas, SkScalar weight, const SkPaint& paint)
{ | |
| 33 SkPath path; | |
| 34 path.moveTo(100, 100); | |
| 35 path.conicTo(300, 100, 300, 300, weight); | |
| 36 canvas->drawPath(path, paint); | |
| 37 } | |
| 38 | |
| 39 static void test_conic(SkCanvas* canvas) { | |
| 40 SkPaint paint; | |
| 41 paint.setAntiAlias(true); | |
| 42 paint.setStyle(SkPaint::kStroke_Style); | |
| 43 | |
| 44 static const struct { | |
| 45 SkScalar fWeight; | |
| 46 SkColor fColor; | |
| 47 } gRec[] = { | |
| 48 { 2 , SK_ColorRED }, | |
| 49 { 1 , SK_ColorGREEN }, | |
| 50 { 0.5f, SK_ColorBLUE }, | |
| 51 }; | |
| 52 | |
| 53 for (SkScalar width = 0; width <= 20; width += 20) { | |
| 54 canvas->save(); | |
| 55 paint.setStrokeWidth(width); | |
| 56 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | |
| 57 paint.setColor(gRec[i].fColor); | |
| 58 draw_conic(canvas, gRec[i].fWeight, paint); | |
| 59 canvas->translate(-30, 30); | |
| 60 } | |
| 61 canvas->restore(); | |
| 62 canvas->translate(300, 0); | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 #include "SkGradientShader.h" | |
| 67 static void test_shallow_gradient(SkCanvas* canvas, SkScalar width, SkScalar hei
ght) { | |
| 68 SkColor colors[] = { 0xFF7F7F7F, 0xFF7F7F7F, 0xFF000000 }; | |
| 69 SkScalar pos[] = { 0, 0.35f, SK_Scalar1 }; | |
| 70 SkPoint pts[] = { { 0, 0 }, { width, height } }; | |
| 71 SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, | |
| 72 SK_ARRAY_COUNT(colors), | |
| 73 SkShader::kClamp_TileMode); | |
| 74 SkPaint paint; | |
| 75 paint.setShader(s)->unref(); | |
| 76 canvas->drawPaint(paint); | |
| 77 } | |
| 78 | |
| 79 #include "SkDashPathEffect.h" | |
| 80 static void test_giant_dash(SkCanvas* canvas) { | |
| 81 SkPaint paint; | |
| 82 const SkScalar intervals[] = { SK_Scalar1, SK_Scalar1 }; | |
| 83 | |
| 84 paint.setStrokeWidth(2); | |
| 85 paint.setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref(); | |
| 86 | |
| 87 SkScalar big = 500 * 1000; | |
| 88 | |
| 89 canvas->drawLine(10, 10, big, 10, paint); | |
| 90 canvas->drawLine(-big, 20, 500, 20, paint); | |
| 91 canvas->drawLine(-big, 30, big, 30, paint); | |
| 92 | |
| 93 const SkScalar intervals2[] = { 20, 5, 10, 5 }; | |
| 94 paint.setPathEffect(new SkDashPathEffect(intervals2, 4, 17))->unref(); | |
| 95 | |
| 96 canvas->translate(0, 40); | |
| 97 SkScalar x = -500; | |
| 98 SkScalar width = 3173; | |
| 99 for (int i = 0; i < 40; ++i) { | |
| 100 if (i > 10) | |
| 101 canvas->drawLine(x, 0, x + width, 0, paint); | |
| 102 x += 1; | |
| 103 canvas->translate(0, 4); | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 | |
| 108 | |
| 109 // Reproduces bug found here: http://jsfiddle.net/R8Cu5/1/ | |
| 110 // | |
| 111 #include "SkGradientShader.h" | |
| 112 static void test_grad(SkCanvas* canvas) { | |
| 113 SkPoint pts[] = { | |
| 114 { 478.544067f, -84.2041016f }, | |
| 115 { 602.455933f, 625.204102f }, | |
| 116 }; | |
| 117 SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, SK_ColorRED, SK_ColorRED
}; | |
| 118 SkScalar pos[] = { 0, 0.3f, 0.3f, 1.0f }; | |
| 119 SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 4, SkShader::
kClamp_TileMode); | |
| 120 SkPaint p; | |
| 121 p.setShader(s)->unref(); | |
| 122 canvas->drawPaint(p); | |
| 123 } | |
| 124 | |
| 125 static SkCanvas* MakeCanvas(const SkIRect& bounds) { | |
| 126 SkBitmap bm; | |
| 127 bm.allocN32Pixels(bounds.width(), bounds.height()); | |
| 128 bm.eraseColor(SK_ColorTRANSPARENT); | |
| 129 | |
| 130 SkCanvas* canvas = new SkCanvas(bm); | |
| 131 canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop))
; | |
| 132 return canvas; | |
| 133 } | |
| 134 | |
| 135 #ifdef SK_DEBUG | |
| 136 static void GetBitmap(const SkCanvas* canvas, SkBitmap* bm) { | |
| 137 *bm = canvas->getDevice()->accessBitmap(false); | |
| 138 } | |
| 139 #endif | |
| 140 | |
| 141 static void compare_canvas(const SkCanvas* a, const SkCanvas* b) { | |
| 142 #ifdef SK_DEBUG | |
| 143 SkBitmap bma, bmb; | |
| 144 GetBitmap(a, &bma); | |
| 145 GetBitmap(b, &bmb); | |
| 146 | |
| 147 SkASSERT(bma.width() == bmb.width()); | |
| 148 SkASSERT(bma.height() == bmb.height()); | |
| 149 | |
| 150 bma.lockPixels(); | |
| 151 bmb.lockPixels(); | |
| 152 for (int y = 0; y < bma.height(); ++y) { | |
| 153 const SkPMColor* rowa = bma.getAddr32(0, y); | |
| 154 const SkPMColor* rowb = bmb.getAddr32(0, y); | |
| 155 SkASSERT(!memcmp(rowa, rowb, bma.width() << 2)); | |
| 156 | |
| 157 for (int x = 1; x < bma.width() - 1; ++x) { | |
| 158 SkASSERT(0xFF000000 == rowa[x]); | |
| 159 SkASSERT(0xFF000000 == rowb[x]); | |
| 160 } | |
| 161 } | |
| 162 #endif | |
| 163 } | |
| 164 | |
| 165 static void drawRectAsPath(SkCanvas* canvas, const SkRect& r, const SkPaint& p)
{ | |
| 166 SkPath path; | |
| 167 path.addRect(r); | |
| 168 canvas->drawPath(path, p); | |
| 169 } | |
| 170 | |
| 171 static void test_maskFromPath(const SkPath& path) { | |
| 172 SkIRect bounds; | |
| 173 path.getBounds().roundOut(&bounds); | |
| 174 | |
| 175 SkPaint paint; | |
| 176 paint.setAntiAlias(true); | |
| 177 | |
| 178 SkAutoTUnref<SkCanvas> path_canvas(MakeCanvas(bounds)); | |
| 179 path_canvas->drawPath(path, paint); | |
| 180 | |
| 181 SkAutoTUnref<SkCanvas> rect_canvas(MakeCanvas(bounds)); | |
| 182 drawRectAsPath(rect_canvas, path.getBounds(), paint); | |
| 183 | |
| 184 compare_canvas(path_canvas, rect_canvas); | |
| 185 } | |
| 186 | |
| 187 static void test_mask() { | |
| 188 for (int i = 1; i <= 20; ++i) { | |
| 189 const SkScalar dx = SK_Scalar1 / i; | |
| 190 const SkRect constr = SkRect::MakeWH(dx, SkIntToScalar(2)); | |
| 191 for (int n = 2; n < 20; ++n) { | |
| 192 SkPath path; | |
| 193 path.setFillType(SkPath::kEvenOdd_FillType); | |
| 194 SkRect r = constr; | |
| 195 while (r.fRight < SkIntToScalar(4)) { | |
| 196 path.addRect(r); | |
| 197 r.offset(dx, 0); | |
| 198 } | |
| 199 test_maskFromPath(path); | |
| 200 } | |
| 201 } | |
| 202 } | |
| 203 | |
| 204 /** Draw a 2px border around the target, then red behind the target; | 12 /** Draw a 2px border around the target, then red behind the target; |
| 205 set the clip to match the target, then draw >> the target in blue. | 13 set the clip to match the target, then draw >> the target in blue. |
| 206 */ | 14 */ |
| 207 | 15 |
| 208 static void draw (SkCanvas* canvas, SkRect& target, int x, int y) { | 16 static void draw(SkCanvas* canvas, SkRect& target, int x, int y) { |
| 209 SkPaint borderPaint; | 17 SkPaint borderPaint; |
| 210 borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0)); | 18 borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0)); |
| 211 borderPaint.setAntiAlias(true); | 19 borderPaint.setAntiAlias(true); |
| 212 SkPaint backgroundPaint; | 20 SkPaint backgroundPaint; |
| 213 backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0)); | 21 backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0)); |
| 214 backgroundPaint.setAntiAlias(true); | 22 backgroundPaint.setAntiAlias(true); |
| 215 SkPaint foregroundPaint; | 23 SkPaint foregroundPaint; |
| 216 foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD)); | 24 foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD)); |
| 217 foregroundPaint.setAntiAlias(true); | 25 foregroundPaint.setAntiAlias(true); |
| 218 | 26 |
| 219 canvas->save(); | 27 canvas->save(); |
| 220 canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); | 28 canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); |
| 221 target.inset(SkIntToScalar(-2), SkIntToScalar(-2)); | 29 target.inset(SkIntToScalar(-2), SkIntToScalar(-2)); |
| 222 canvas->drawRect(target, borderPaint); | 30 canvas->drawRect(target, borderPaint); |
| 223 target.inset(SkIntToScalar(2), SkIntToScalar(2)); | 31 target.inset(SkIntToScalar(2), SkIntToScalar(2)); |
| 224 canvas->drawRect(target, backgroundPaint); | 32 canvas->drawRect(target, backgroundPaint); |
| 225 canvas->clipRect(target, SkRegion::kIntersect_Op, true); | 33 canvas->clipRect(target, SkRegion::kIntersect_Op, true); |
| 226 target.inset(SkIntToScalar(-4), SkIntToScalar(-4)); | 34 target.inset(SkIntToScalar(-4), SkIntToScalar(-4)); |
| 227 canvas->drawRect(target, foregroundPaint); | 35 canvas->drawRect(target, foregroundPaint); |
| 228 canvas->restore(); | 36 canvas->restore(); |
| 229 } | 37 } |
| 230 | 38 |
| 231 static void draw_square (SkCanvas* canvas, int x, int y) { | 39 static void draw_square(SkCanvas* canvas, int x, int y) { |
| 232 SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1)); | 40 SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1)); |
| 233 draw(canvas, target, x, y); | 41 draw(canvas, target, x, y); |
| 234 } | 42 } |
| 235 | 43 |
| 236 static void draw_column (SkCanvas* canvas, int x, int y) { | 44 static void draw_column(SkCanvas* canvas, int x, int y) { |
| 237 SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1)); | 45 SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1)); |
| 238 draw(canvas, target, x, y); | 46 draw(canvas, target, x, y); |
| 239 } | 47 } |
| 240 | 48 |
| 241 static void draw_bar (SkCanvas* canvas, int x, int y) { | 49 static void draw_bar(SkCanvas* canvas, int x, int y) { |
| 242 SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1)); | 50 SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1)); |
| 243 draw(canvas, target, x, y); | 51 draw(canvas, target, x, y); |
| 244 } | 52 } |
| 245 | 53 |
| 246 static void draw_rect_tests (SkCanvas* canvas) { | 54 static void draw_rect_tests(SkCanvas* canvas) { |
| 247 draw_square(canvas, 10, 10); | 55 draw_square(canvas, 10, 10); |
| 248 draw_column(canvas, 30, 10); | 56 draw_column(canvas, 30, 10); |
| 249 draw_bar(canvas, 10, 30); | 57 draw_bar(canvas, 10, 30); |
| 250 } | 58 } |
| 251 | 59 |
| 252 /** | 60 /** |
| 253 Test a set of clipping problems discovered while writing blitAntiRect, | 61 Test a set of clipping problems discovered while writing blitAntiRect, |
| 254 and test all the code paths through the clipping blitters. | 62 and test all the code paths through the clipping blitters. |
| 255 Each region should show as a blue center surrounded by a 2px green | 63 Each region should show as a blue center surrounded by a 2px green |
| 256 border, with no red. | 64 border, with no red. |
| 257 */ | 65 */ |
| 258 | 66 |
| 259 class AAClipGM : public skiagm::GM { | 67 class AAClipGM : public skiagm::GM { |
| 260 public: | 68 public: |
| 261 AAClipGM() { | 69 AAClipGM() { |
| 262 | 70 |
| 263 } | 71 } |
| 264 | 72 |
| 265 protected: | 73 protected: |
| 266 virtual SkString onShortName() SK_OVERRIDE { | 74 virtual SkString onShortName() SK_OVERRIDE { |
| 267 return SkString("aaclip"); | 75 return SkString("aaclip"); |
| 268 } | 76 } |
| 269 | 77 |
| 270 virtual SkISize onISize() SK_OVERRIDE { | 78 virtual SkISize onISize() SK_OVERRIDE { |
| 271 return SkISize::Make(640, 480); | 79 return SkISize::Make(640, 480); |
| 272 } | 80 } |
| 273 | 81 |
| 274 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 82 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
| 275 if (false) { test_quadstroke(canvas); return; } | |
| 276 if (false) { test_conic(canvas); return; } | |
| 277 if (false) { | |
| 278 SkRect bounds; | |
| 279 canvas->getClipBounds(&bounds); | |
| 280 test_shallow_gradient(canvas, bounds.width(), bounds.height()); retu
rn; | |
| 281 } | |
| 282 if (false) { | |
| 283 test_giant_dash(canvas); return; | |
| 284 } | |
| 285 if (false) { | |
| 286 test_grad(canvas); return; | |
| 287 } | |
| 288 if (false) { // avoid bit rot, suppress warning | |
| 289 test_mask(); | |
| 290 } | |
| 291 | |
| 292 // Initial pixel-boundary-aligned draw | 83 // Initial pixel-boundary-aligned draw |
| 293 draw_rect_tests(canvas); | 84 draw_rect_tests(canvas); |
| 294 | 85 |
| 295 // Repeat 4x with .2, .4, .6, .8 px offsets | 86 // Repeat 4x with .2, .4, .6, .8 px offsets |
| 296 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 87 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); |
| 297 canvas->translate(SkIntToScalar(50), 0); | 88 canvas->translate(SkIntToScalar(50), 0); |
| 298 draw_rect_tests(canvas); | 89 draw_rect_tests(canvas); |
| 299 | 90 |
| 300 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 91 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); |
| 301 canvas->translate(SkIntToScalar(50), 0); | 92 canvas->translate(SkIntToScalar(50), 0); |
| 302 draw_rect_tests(canvas); | 93 draw_rect_tests(canvas); |
| 303 | 94 |
| 304 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 95 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); |
| 305 canvas->translate(SkIntToScalar(50), 0); | 96 canvas->translate(SkIntToScalar(50), 0); |
| 306 draw_rect_tests(canvas); | 97 draw_rect_tests(canvas); |
| 307 | 98 |
| 308 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 99 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); |
| 309 canvas->translate(SkIntToScalar(50), 0); | 100 canvas->translate(SkIntToScalar(50), 0); |
| 310 draw_rect_tests(canvas); | 101 draw_rect_tests(canvas); |
| 311 } | 102 } |
| 312 | 103 |
| 313 virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; } | 104 virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; } |
| 314 | 105 |
| 315 private: | 106 private: |
| 316 typedef skiagm::GM INHERITED; | 107 typedef skiagm::GM INHERITED; |
| 317 }; | 108 }; |
| 318 | 109 |
| 319 DEF_GM( return SkNEW(AAClipGM); ) | 110 DEF_GM( return SkNEW(AAClipGM); ) |
| OLD | NEW |