| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2011 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 "gm.h" | 
|  | 9 | #include "SkCanvas.h" | 
|  | 10 | #include "SkPath.h" | 
|  | 11 |  | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 12 | /** Draw a 2px border around the target, then red behind the target; | 
|  | 13 | set the clip to match the target, then draw >> the target in blue. | 
|  | 14 | */ | 
|  | 15 |  | 
| commit-bot@chromium.org | c3bd8af | 2014-02-13 17:14:46 +0000 | [diff] [blame] | 16 | static void draw(SkCanvas* canvas, SkRect& target, int x, int y) { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 17 | SkPaint borderPaint; | 
|  | 18 | borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0)); | 
|  | 19 | borderPaint.setAntiAlias(true); | 
|  | 20 | SkPaint backgroundPaint; | 
|  | 21 | backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0)); | 
|  | 22 | backgroundPaint.setAntiAlias(true); | 
|  | 23 | SkPaint foregroundPaint; | 
|  | 24 | foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD)); | 
|  | 25 | foregroundPaint.setAntiAlias(true); | 
|  | 26 |  | 
|  | 27 | canvas->save(); | 
| tomhudson@google.com | abfa8d1 | 2011-12-28 19:40:48 +0000 | [diff] [blame] | 28 | canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); | 
|  | 29 | target.inset(SkIntToScalar(-2), SkIntToScalar(-2)); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 30 | canvas->drawRect(target, borderPaint); | 
| tomhudson@google.com | abfa8d1 | 2011-12-28 19:40:48 +0000 | [diff] [blame] | 31 | target.inset(SkIntToScalar(2), SkIntToScalar(2)); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 32 | canvas->drawRect(target, backgroundPaint); | 
|  | 33 | canvas->clipRect(target, SkRegion::kIntersect_Op, true); | 
| tomhudson@google.com | abfa8d1 | 2011-12-28 19:40:48 +0000 | [diff] [blame] | 34 | target.inset(SkIntToScalar(-4), SkIntToScalar(-4)); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 35 | canvas->drawRect(target, foregroundPaint); | 
|  | 36 | canvas->restore(); | 
|  | 37 | } | 
|  | 38 |  | 
| commit-bot@chromium.org | c3bd8af | 2014-02-13 17:14:46 +0000 | [diff] [blame] | 39 | static void draw_square(SkCanvas* canvas, int x, int y) { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 40 | SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1)); | 
|  | 41 | draw(canvas, target, x, y); | 
|  | 42 | } | 
|  | 43 |  | 
| commit-bot@chromium.org | c3bd8af | 2014-02-13 17:14:46 +0000 | [diff] [blame] | 44 | static void draw_column(SkCanvas* canvas, int x, int y) { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 45 | SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1)); | 
|  | 46 | draw(canvas, target, x, y); | 
|  | 47 | } | 
|  | 48 |  | 
| commit-bot@chromium.org | c3bd8af | 2014-02-13 17:14:46 +0000 | [diff] [blame] | 49 | static void draw_bar(SkCanvas* canvas, int x, int y) { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 50 | SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1)); | 
|  | 51 | draw(canvas, target, x, y); | 
|  | 52 | } | 
|  | 53 |  | 
| commit-bot@chromium.org | c3bd8af | 2014-02-13 17:14:46 +0000 | [diff] [blame] | 54 | static void draw_rect_tests(SkCanvas* canvas) { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 55 | draw_square(canvas, 10, 10); | 
|  | 56 | draw_column(canvas, 30, 10); | 
|  | 57 | draw_bar(canvas, 10, 30); | 
|  | 58 | } | 
|  | 59 |  | 
|  | 60 | /** | 
|  | 61 | Test a set of clipping problems discovered while writing blitAntiRect, | 
|  | 62 | and test all the code paths through the clipping blitters. | 
|  | 63 | Each region should show as a blue center surrounded by a 2px green | 
|  | 64 | border, with no red. | 
|  | 65 | */ | 
|  | 66 |  | 
| reed@google.com | ff26b7e | 2013-05-23 17:04:19 +0000 | [diff] [blame] | 67 | class AAClipGM : public skiagm::GM { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 68 | public: | 
|  | 69 | AAClipGM() { | 
| reed@google.com | 7112173 | 2012-09-18 15:14:33 +0000 | [diff] [blame] | 70 |  | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 71 | } | 
|  | 72 |  | 
|  | 73 | protected: | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 74 | SkString onShortName() override { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 75 | return SkString("aaclip"); | 
|  | 76 | } | 
|  | 77 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 78 | SkISize onISize() override { | 
| commit-bot@chromium.org | 5d0b150 | 2014-04-14 15:02:19 +0000 | [diff] [blame] | 79 | return SkISize::Make(240, 120); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 80 | } | 
|  | 81 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 82 | void onDraw(SkCanvas* canvas) override { | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 83 | // Initial pixel-boundary-aligned draw | 
|  | 84 | draw_rect_tests(canvas); | 
|  | 85 |  | 
|  | 86 | // Repeat 4x with .2, .4, .6, .8 px offsets | 
|  | 87 | canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 
| tomhudson@google.com | abfa8d1 | 2011-12-28 19:40:48 +0000 | [diff] [blame] | 88 | canvas->translate(SkIntToScalar(50), 0); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 89 | draw_rect_tests(canvas); | 
|  | 90 |  | 
|  | 91 | canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 
| tomhudson@google.com | abfa8d1 | 2011-12-28 19:40:48 +0000 | [diff] [blame] | 92 | canvas->translate(SkIntToScalar(50), 0); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 93 | draw_rect_tests(canvas); | 
|  | 94 |  | 
|  | 95 | canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 
| tomhudson@google.com | abfa8d1 | 2011-12-28 19:40:48 +0000 | [diff] [blame] | 96 | canvas->translate(SkIntToScalar(50), 0); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 97 | draw_rect_tests(canvas); | 
|  | 98 |  | 
|  | 99 | canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); | 
| tomhudson@google.com | abfa8d1 | 2011-12-28 19:40:48 +0000 | [diff] [blame] | 100 | canvas->translate(SkIntToScalar(50), 0); | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 101 | draw_rect_tests(canvas); | 
|  | 102 | } | 
|  | 103 |  | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 104 | private: | 
| reed@google.com | ff26b7e | 2013-05-23 17:04:19 +0000 | [diff] [blame] | 105 | typedef skiagm::GM INHERITED; | 
| tomhudson@google.com | ef279d3 | 2011-12-21 14:27:14 +0000 | [diff] [blame] | 106 | }; | 
|  | 107 |  | 
| halcanary | 385fe4d | 2015-08-26 13:07:48 -0700 | [diff] [blame] | 108 | DEF_GM(return new AAClipGM;) | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 109 |  | 
|  | 110 | ///////////////////////////////////////////////////////////////////////// | 
|  | 111 |  | 
|  | 112 | #ifdef SK_BUILD_FOR_MAC | 
|  | 113 |  | 
|  | 114 | static SkCanvas* make_canvas(const SkBitmap& bm) { | 
|  | 115 | const SkImageInfo& info = bm.info(); | 
|  | 116 | if (info.bytesPerPixel() == 4) { | 
|  | 117 | return SkCanvas::NewRasterDirectN32(info.width(), info.height(), | 
|  | 118 | (SkPMColor*)bm.getPixels(), | 
|  | 119 | bm.rowBytes()); | 
|  | 120 | } else { | 
| halcanary | 385fe4d | 2015-08-26 13:07:48 -0700 | [diff] [blame] | 121 | return new SkCanvas(bm); | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 122 | } | 
|  | 123 | } | 
|  | 124 |  | 
|  | 125 | #include "SkCGUtils.h" | 
|  | 126 | static void test_image(SkCanvas* canvas, const SkImageInfo& info) { | 
|  | 127 | SkBitmap bm; | 
|  | 128 | bm.allocPixels(info); | 
|  | 129 |  | 
|  | 130 | SkAutoTUnref<SkCanvas> newc(make_canvas(bm)); | 
|  | 131 | if (info.isOpaque()) { | 
|  | 132 | bm.eraseColor(SK_ColorGREEN); | 
|  | 133 | } else { | 
|  | 134 | bm.eraseColor(0); | 
|  | 135 | } | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 136 |  | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 137 | SkPaint paint; | 
|  | 138 | paint.setAntiAlias(true); | 
|  | 139 | paint.setColor(SK_ColorBLUE); | 
|  | 140 | newc->drawCircle(50, 50, 49, paint); | 
|  | 141 | canvas->drawBitmap(bm, 10, 10); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 142 |  | 
| halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 143 | CGImageRef image = SkCreateCGImageRefWithColorspace(bm, nullptr); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 144 |  | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 145 | SkBitmap bm2; | 
|  | 146 | SkCreateBitmapFromCGImage(&bm2, image); | 
|  | 147 | CGImageRelease(image); | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 148 |  | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 149 | canvas->drawBitmap(bm2, 10, 120); | 
|  | 150 | } | 
|  | 151 |  | 
|  | 152 | class CGImageGM : public skiagm::GM { | 
|  | 153 | public: | 
|  | 154 | CGImageGM() {} | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 155 |  | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 156 | protected: | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 157 | SkString onShortName() override { | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 158 | return SkString("cgimage"); | 
|  | 159 | } | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 160 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 161 | SkISize onISize() override { | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 162 | return SkISize::Make(800, 250); | 
|  | 163 | } | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 164 |  | 
| mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 165 | void onDraw(SkCanvas* canvas) override { | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 166 | const struct { | 
|  | 167 | SkColorType fCT; | 
|  | 168 | SkAlphaType fAT; | 
|  | 169 | } rec[] = { | 
|  | 170 | { kRGB_565_SkColorType, kOpaque_SkAlphaType }, | 
|  | 171 |  | 
|  | 172 | { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, | 
|  | 173 | { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType }, | 
|  | 174 | { kRGBA_8888_SkColorType, kOpaque_SkAlphaType }, | 
|  | 175 |  | 
|  | 176 | { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, | 
|  | 177 | { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, | 
|  | 178 | { kBGRA_8888_SkColorType, kOpaque_SkAlphaType }, | 
|  | 179 | }; | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 180 |  | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 181 | for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) { | 
|  | 182 | SkImageInfo info = SkImageInfo::Make(100, 100, rec[i].fCT, rec[i].fAT); | 
|  | 183 | test_image(canvas, info); | 
|  | 184 | canvas->translate(info.width() + 10, 0); | 
|  | 185 | } | 
|  | 186 | } | 
| skia.committer@gmail.com | ede0c5c | 2014-04-23 03:04:11 +0000 | [diff] [blame] | 187 |  | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 188 | private: | 
|  | 189 | typedef skiagm::GM INHERITED; | 
|  | 190 | }; | 
|  | 191 |  | 
| bsalomon@google.com | 2a9e3ad | 2014-04-23 18:05:36 +0000 | [diff] [blame] | 192 | #if 0 // Disabled pending fix from reed@ | 
| halcanary | 385fe4d | 2015-08-26 13:07:48 -0700 | [diff] [blame] | 193 | DEF_GM( return new CGImageGM; ) | 
| bsalomon@google.com | 2a9e3ad | 2014-04-23 18:05:36 +0000 | [diff] [blame] | 194 | #endif | 
| commit-bot@chromium.org | 60b5dce | 2014-04-22 20:24:33 +0000 | [diff] [blame] | 195 | #endif | 
| reed | 8f76cb9 | 2015-04-22 17:38:23 -0700 | [diff] [blame] | 196 |  | 
|  | 197 | /////////////////////////////////////////////////////////////////////////////////////////////////// | 
|  | 198 |  | 
| halcanary | 6950de6 | 2015-11-07 05:29:00 -0800 | [diff] [blame] | 199 | // https://bug.skia.org/3716 | 
| reed | 8f76cb9 | 2015-04-22 17:38:23 -0700 | [diff] [blame] | 200 | class ClipCubicGM : public skiagm::GM { | 
|  | 201 | const SkScalar W = 100; | 
|  | 202 | const SkScalar H = 240; | 
|  | 203 |  | 
|  | 204 | SkPath fVPath, fHPath; | 
|  | 205 | public: | 
|  | 206 | ClipCubicGM() { | 
|  | 207 | fVPath.moveTo(W, 0); | 
|  | 208 | fVPath.cubicTo(W, H-10, 0, 10, 0, H); | 
|  | 209 |  | 
|  | 210 | SkMatrix pivot; | 
|  | 211 | pivot.setRotate(90, W/2, H/2); | 
|  | 212 | fVPath.transform(pivot, &fHPath); | 
|  | 213 | } | 
|  | 214 |  | 
|  | 215 | protected: | 
|  | 216 | SkString onShortName() override { | 
|  | 217 | return SkString("clipcubic"); | 
|  | 218 | } | 
|  | 219 |  | 
|  | 220 | SkISize onISize() override { | 
|  | 221 | return SkISize::Make(400, 410); | 
|  | 222 | } | 
|  | 223 |  | 
|  | 224 | void doDraw(SkCanvas* canvas, const SkPath& path) { | 
|  | 225 | SkPaint paint; | 
|  | 226 | paint.setAntiAlias(true); | 
|  | 227 |  | 
| caryclark | 1259601 | 2015-07-29 05:27:47 -0700 | [diff] [blame] | 228 | paint.setColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); | 
| reed | 8f76cb9 | 2015-04-22 17:38:23 -0700 | [diff] [blame] | 229 | canvas->drawPath(path, paint); | 
|  | 230 |  | 
|  | 231 | paint.setColor(SK_ColorRED); | 
|  | 232 | paint.setStyle(SkPaint::kStroke_Style); | 
|  | 233 | canvas->drawPath(path, paint); | 
|  | 234 | } | 
|  | 235 |  | 
|  | 236 | void drawAndClip(SkCanvas* canvas, const SkPath& path, SkScalar dx, SkScalar dy) { | 
|  | 237 | SkAutoCanvasRestore acr(canvas, true); | 
|  | 238 |  | 
|  | 239 | SkRect r = SkRect::MakeXYWH(0, H/4, W, H/2); | 
|  | 240 | SkPaint paint; | 
| caryclark | 1259601 | 2015-07-29 05:27:47 -0700 | [diff] [blame] | 241 | paint.setColor(sk_tool_utils::color_to_565(0xFF8888FF)); | 
| reed | 8f76cb9 | 2015-04-22 17:38:23 -0700 | [diff] [blame] | 242 |  | 
|  | 243 | canvas->drawRect(r, paint); | 
|  | 244 | this->doDraw(canvas, path); | 
|  | 245 |  | 
|  | 246 | canvas->translate(dx, dy); | 
|  | 247 |  | 
|  | 248 | canvas->drawRect(r, paint); | 
|  | 249 | canvas->clipRect(r); | 
|  | 250 | this->doDraw(canvas, path); | 
|  | 251 | } | 
|  | 252 |  | 
|  | 253 | void onDraw(SkCanvas* canvas) override { | 
|  | 254 | canvas->translate(80, 10); | 
|  | 255 | this->drawAndClip(canvas, fVPath, 200, 0); | 
|  | 256 | canvas->translate(0, 200); | 
|  | 257 | this->drawAndClip(canvas, fHPath, 200, 0); | 
|  | 258 | } | 
|  | 259 |  | 
|  | 260 | private: | 
|  | 261 | typedef skiagm::GM INHERITED; | 
|  | 262 | }; | 
| halcanary | 385fe4d | 2015-08-26 13:07:48 -0700 | [diff] [blame] | 263 | DEF_GM(return new ClipCubicGM;) |