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/gm.h" 9#include "include/core/SkBitmap.h" 10#include "include/core/SkBlendMode.h" 11#include "include/core/SkCanvas.h" 12#include "include/core/SkColor.h" 13#include "include/core/SkMatrix.h" 14#include "include/core/SkPaint.h" 15#include "include/core/SkPathBuilder.h" 16#include "include/core/SkRect.h" 17#include "include/core/SkScalar.h" 18#include "include/core/SkSize.h" 19#include "include/core/SkString.h" 20#include "src/core/SkCanvasPriv.h" 21#include "tools/ToolUtils.h" 22 23/** Draw a 2px border around the target, then red behind the target; 24 set the clip to match the target, then draw >> the target in blue. 25*/ 26 27static void draw(SkCanvas* canvas, SkRect& target, int x, int y) { 28 SkPaint borderPaint; 29 borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0)); 30 borderPaint.setAntiAlias(true); 31 SkPaint backgroundPaint; 32 backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0)); 33 backgroundPaint.setAntiAlias(true); 34 SkPaint foregroundPaint; 35 foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD)); 36 foregroundPaint.setAntiAlias(true); 37 38 canvas->save(); 39 canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 40 target.inset(SkIntToScalar(-2), SkIntToScalar(-2)); 41 canvas->drawRect(target, borderPaint); 42 target.inset(SkIntToScalar(2), SkIntToScalar(2)); 43 canvas->drawRect(target, backgroundPaint); 44 canvas->clipRect(target, true); 45 target.inset(SkIntToScalar(-4), SkIntToScalar(-4)); 46 canvas->drawRect(target, foregroundPaint); 47 canvas->restore(); 48} 49 50static void draw_square(SkCanvas* canvas, int x, int y) { 51 SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1)); 52 draw(canvas, target, x, y); 53} 54 55static void draw_column(SkCanvas* canvas, int x, int y) { 56 SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1)); 57 draw(canvas, target, x, y); 58} 59 60static void draw_bar(SkCanvas* canvas, int x, int y) { 61 SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1)); 62 draw(canvas, target, x, y); 63} 64 65static void draw_rect_tests(SkCanvas* canvas) { 66 draw_square(canvas, 10, 10); 67 draw_column(canvas, 30, 10); 68 draw_bar(canvas, 10, 30); 69} 70 71/** 72 Test a set of clipping problems discovered while writing blitAntiRect, 73 and test all the code paths through the clipping blitters. 74 Each region should show as a blue center surrounded by a 2px green 75 border, with no red. 76*/ 77DEF_SIMPLE_GM(aaclip, canvas, 240, 120) { 78 // Initial pixel-boundary-aligned draw 79 draw_rect_tests(canvas); 80 81 // Repeat 4x with .2, .4, .6, .8 px offsets 82 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); 83 canvas->translate(SkIntToScalar(50), 0); 84 draw_rect_tests(canvas); 85 86 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); 87 canvas->translate(SkIntToScalar(50), 0); 88 draw_rect_tests(canvas); 89 90 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); 91 canvas->translate(SkIntToScalar(50), 0); 92 draw_rect_tests(canvas); 93 94 canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5); 95 canvas->translate(SkIntToScalar(50), 0); 96 draw_rect_tests(canvas); 97} 98 99///////////////////////////////////////////////////////////////////////// 100 101#ifdef SK_BUILD_FOR_MAC 102 103#include "include/utils/mac/SkCGUtils.h" 104 105static std::unique_ptr<SkCanvas> make_canvas(const SkBitmap& bm) { 106 return SkCanvas::MakeRasterDirect(bm.info(), bm.getPixels(), bm.rowBytes()); 107} 108 109static void test_image(SkCanvas* canvas, const SkImageInfo& info) { 110 SkBitmap bm; 111 bm.allocPixels(info); 112 113 if (info.isOpaque()) { 114 bm.eraseColor(SK_ColorGREEN); 115 } else { 116 bm.eraseColor(0); 117 } 118 119 SkPaint paint; 120 paint.setAntiAlias(true); 121 paint.setColor(SK_ColorBLUE); 122 make_canvas(bm)->drawCircle(50, 50, 49, paint); 123 canvas->drawImage(bm.asImage(), 10, 10); 124 125 CGImageRef image = SkCreateCGImageRefWithColorspace(bm, nullptr); 126 127 SkBitmap bm2; 128 SkCreateBitmapFromCGImage(&bm2, image); 129 canvas->drawImage(bm2.asImage(), 10, 120); 130 canvas->drawImage(SkMakeImageFromCGImage(image), 10, 120 + bm2.height() + 10); 131 132 CGImageRelease(image); 133} 134 135DEF_SIMPLE_GM(cgimage, canvas, 800, 250) { 136 const struct { 137 SkColorType fCT; 138 SkAlphaType fAT; 139 } rec[] = { 140 { kRGB_565_SkColorType, kOpaque_SkAlphaType }, 141 142 { kRGBA_8888_SkColorType, kPremul_SkAlphaType }, 143 { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType }, 144 { kRGBA_8888_SkColorType, kOpaque_SkAlphaType }, 145 146 { kBGRA_8888_SkColorType, kPremul_SkAlphaType }, 147 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType }, 148 { kBGRA_8888_SkColorType, kOpaque_SkAlphaType }, 149 }; 150 151 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) { 152 SkImageInfo info = SkImageInfo::Make(100, 100, rec[i].fCT, rec[i].fAT); 153 test_image(canvas, info); 154 canvas->translate(info.width() + 10, 0); 155 } 156} 157 158#endif 159 160/////////////////////////////////////////////////////////////////////////////////////////////////// 161 162// https://bug.skia.org/3716 163class ClipCubicGM : public skiagm::GM { 164 const SkScalar W = 100; 165 const SkScalar H = 240; 166 167 SkPath fVPath, fHPath; 168public: 169 ClipCubicGM() { 170 fVPath = SkPathBuilder().moveTo(W, 0) 171 .cubicTo(W, H-10, 0, 10, 0, H) 172 .detach(); 173 174 SkMatrix pivot; 175 pivot.setRotate(90, W/2, H/2); 176 fHPath = fVPath.makeTransform(pivot); 177 } 178 179protected: 180 SkString onShortName() override { 181 return SkString("clipcubic"); 182 } 183 184 SkISize onISize() override { 185 return SkISize::Make(400, 410); 186 } 187 188 void doDraw(SkCanvas* canvas, const SkPath& path) { 189 SkPaint paint; 190 paint.setAntiAlias(true); 191 192 paint.setColor(0xFFCCCCCC); 193 canvas->drawPath(path, paint); 194 195 paint.setColor(SK_ColorRED); 196 paint.setStyle(SkPaint::kStroke_Style); 197 canvas->drawPath(path, paint); 198 } 199 200 void drawAndClip(SkCanvas* canvas, const SkPath& path, SkScalar dx, SkScalar dy) { 201 SkAutoCanvasRestore acr(canvas, true); 202 203 SkRect r = SkRect::MakeXYWH(0, H/4, W, H/2); 204 SkPaint paint; 205 paint.setColor(ToolUtils::color_to_565(0xFF8888FF)); 206 207 canvas->drawRect(r, paint); 208 this->doDraw(canvas, path); 209 210 canvas->translate(dx, dy); 211 212 canvas->drawRect(r, paint); 213 canvas->clipRect(r); 214 this->doDraw(canvas, path); 215 } 216 217 void onDraw(SkCanvas* canvas) override { 218 canvas->translate(80, 10); 219 this->drawAndClip(canvas, fVPath, 200, 0); 220 canvas->translate(0, 200); 221 this->drawAndClip(canvas, fHPath, 200, 0); 222 } 223 224private: 225 using INHERITED = skiagm::GM; 226}; 227DEF_GM(return new ClipCubicGM;) 228