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 "gm.h" 9 #include "SkCanvas.h" 10 #include "SkPaint.h" 11 #include "SkPath.h" 12 #include "SkRect.h" 13 14 namespace skiagm { 15 16 /* 17 * This GM exercises the flags to SkCanvas::save(). The canvas' save() and 18 * restore actions can be limited to only a portion of the canvas' state through 19 * the use of flags when calling save. 20 */ 21 class CanvasStateGM : public GM { 22 SkSize fSize; 23 enum { 24 WIDTH = 150, 25 HEIGHT = 150, 26 }; 27 28 SkPaint fFillPaint; 29 SkPaint fStrokePaint; 30 31 SkPath fPath; 32 33 SkRect fOutlineRect; 34 SkRect fFillRect; 35 36 37 public: 38 CanvasStateGM() { 39 fSize.set(SkIntToScalar(WIDTH), SkIntToScalar(HEIGHT)); 40 41 fFillPaint.setColor(SK_ColorRED); 42 fFillPaint.setStyle(SkPaint::kFill_Style); 43 44 fStrokePaint.setColor(SK_ColorBLUE); 45 fStrokePaint.setStyle(SkPaint::kStroke_Style); 46 fStrokePaint.setStrokeWidth(1); 47 48 fPath.moveTo(25, 25); 49 fPath.lineTo(125, 25); 50 fPath.lineTo(75, 125); 51 fPath.close(); 52 53 fOutlineRect = SkRect::MakeXYWH(1, 1, WIDTH-2, HEIGHT-2); 54 fFillRect = SkRect::MakeXYWH(10, 10, WIDTH-20, HEIGHT-20); 55 } 56 57 protected: 58 virtual SkString onShortName() SK_OVERRIDE { 59 return SkString("canvas-state"); 60 } 61 62 virtual SkISize onISize() SK_OVERRIDE { 63 return SkISize::Make(WIDTH*3, HEIGHT*4); 64 } 65 66 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 67 68 SkCanvas::SaveFlags flags[] = { SkCanvas::kMatrix_SaveFlag, 69 SkCanvas::kClip_SaveFlag, 70 SkCanvas::kMatrixClip_SaveFlag }; 71 72 // columns -- flags 73 // rows -- permutations of setting the clip and matrix 74 for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(flags)); ++i) { 75 for (int j = 0; j < 2; ++j) { 76 for (int k = 0; k < 2; ++k) { 77 this->drawTestPattern(i, (2*j)+k, canvas, flags[i], 78 SkToBool(j), SkToBool(k)); 79 } 80 } 81 } 82 } 83 84 85 virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipPicture_Flag; } 86 87 private: 88 void drawTestPattern(int x, int y, SkCanvas* canvas, 89 SkCanvas::SaveFlags flags, bool doClip, bool doScale) { 90 canvas->save(); 91 canvas->translate(SkIntToScalar(x*WIDTH), SkIntToScalar(y*HEIGHT)); 92 93 canvas->drawRect(fOutlineRect, fStrokePaint); 94 canvas->save(flags); 95 if(doClip) { 96 canvas->clipPath(fPath); 97 } 98 if (doScale) { 99 canvas->scale(SkDoubleToScalar(0.5), SkDoubleToScalar(0.5)); 100 } 101 canvas->restore(); 102 canvas->drawRect(fFillRect, fFillPaint); 103 104 canvas->restore(); 105 } 106 107 typedef GM INHERITED; 108 }; 109 110 ////////////////////////////////////////////////////////////////////////////// 111 112 class CanvasLayerStateGM : public GM { 113 public: 114 CanvasLayerStateGM() { 115 fBluePaint.setColor(SK_ColorBLUE); 116 fBluePaint.setStyle(SkPaint::kFill_Style); 117 118 fRect = SkRect::MakeXYWH(SPACER, SPACER, WIDTH-(2*SPACER), (HEIGHT-(2*SPACER)) / 7); 119 } 120 121 protected: 122 virtual SkString onShortName() SK_OVERRIDE { 123 return SkString("canvas-layer-state"); 124 } 125 126 virtual SkISize onISize() SK_OVERRIDE { 127 return SkISize::Make(WIDTH, HEIGHT); 128 } 129 130 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 131 132 // clear the canvas to red 133 canvas->drawColor(SK_ColorRED); 134 135 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 136 // both rects should appear 137 drawTestPattern(canvas, 255, SkCanvas::kARGB_NoClipLayer_SaveFlag); 138 139 canvas->translate(0, 2*(fRect.height() + 10)); 140 141 // only the top rect should appear 142 drawTestPattern(canvas, 255, SkCanvas::kARGB_ClipLayer_SaveFlag); 143 144 canvas->translate(0, 2*(fRect.height() + 10)); 145 146 // only the bottom rect should appear 147 drawTestPattern(canvas, 0, SkCanvas::kARGB_NoClipLayer_SaveFlag); 148 #endif 149 } 150 151 virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipGPU_Flag; } 152 153 private: 154 // draw a rect within the layer's bounds and again outside the layer's bounds 155 void drawTestPattern(SkCanvas* canvas, U8CPU layerAlpha, SkCanvas::SaveFlags flags) { 156 canvas->saveLayerAlpha(&fRect, layerAlpha, flags); 157 canvas->drawRect(fRect, fBluePaint); 158 canvas->translate(0, fRect.height() + 10); 159 canvas->drawRect(fRect, fBluePaint); 160 canvas->restore(); 161 } 162 163 enum { 164 WIDTH = 400, 165 HEIGHT = 400, 166 SPACER = 10, 167 }; 168 169 SkPaint fBluePaint; 170 SkRect fRect; 171 172 typedef GM INHERITED; 173 }; 174 175 ////////////////////////////////////////////////////////////////////////////// 176 177 DEF_GM( return SkNEW(CanvasStateGM); ) 178 DEF_GM( return SkNEW(CanvasLayerStateGM); ) 179 180 } // end namespace 181