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 "Sample.h" 9 #include "SkAAClip.h" 10 #include "SkCanvas.h" 11 #include "SkColorPriv.h" 12 #include "SkFont.h" 13 #include "SkPaint.h" 14 #include "SkPath.h" 15 #include "SkRandom.h" 16 #include "SkClipOpPriv.h" 17 18 constexpr int W = 150; 19 constexpr int H = 200; 20 21 static void show_text(SkCanvas* canvas, bool doAA) { 22 SkRandom rand; 23 SkPaint paint; 24 SkFont font(nullptr, 20); 25 font.setEdging(doAA ? SkFont::Edging::kSubpixelAntiAlias : SkFont::Edging::kAlias); 26 27 for (int i = 0; i < 200; ++i) { 28 paint.setColor((SK_A32_MASK << SK_A32_SHIFT) | rand.nextU()); 29 canvas->drawString("Hamburgefons", rand.nextSScalar1() * W, rand.nextSScalar1() * H + 20, 30 font, paint); 31 } 32 } 33 34 static void show_fill(SkCanvas* canvas, bool doAA) { 35 SkRandom rand; 36 SkPaint paint; 37 paint.setAntiAlias(doAA); 38 39 for (int i = 0; i < 50; ++i) { 40 SkRect r; 41 SkPath p; 42 43 r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, 44 rand.nextUScalar1() * W, rand.nextUScalar1() * H); 45 paint.setColor(rand.nextU()); 46 canvas->drawRect(r, paint); 47 48 r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, 49 rand.nextUScalar1() * W, rand.nextUScalar1() * H); 50 paint.setColor(rand.nextU()); 51 p.addOval(r); 52 canvas->drawPath(p, paint); 53 } 54 } 55 56 static SkScalar randRange(SkRandom& rand, SkScalar min, SkScalar max) { 57 SkASSERT(min <= max); 58 return min + rand.nextUScalar1() * (max - min); 59 } 60 61 static void show_stroke(SkCanvas* canvas, bool doAA, SkScalar strokeWidth, int n) { 62 SkRandom rand; 63 SkPaint paint; 64 paint.setAntiAlias(doAA); 65 paint.setStyle(SkPaint::kStroke_Style); 66 paint.setStrokeWidth(strokeWidth); 67 68 for (int i = 0; i < n; ++i) { 69 SkRect r; 70 SkPath p; 71 72 r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, 73 rand.nextUScalar1() * W, rand.nextUScalar1() * H); 74 paint.setColor(rand.nextU()); 75 canvas->drawRect(r, paint); 76 77 r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, 78 rand.nextUScalar1() * W, rand.nextUScalar1() * H); 79 paint.setColor(rand.nextU()); 80 p.addOval(r); 81 canvas->drawPath(p, paint); 82 83 const SkScalar minx = -SkIntToScalar(W)/4; 84 const SkScalar maxx = 5*SkIntToScalar(W)/4; 85 const SkScalar miny = -SkIntToScalar(H)/4; 86 const SkScalar maxy = 5*SkIntToScalar(H)/4; 87 paint.setColor(rand.nextU()); 88 canvas->drawLine(randRange(rand, minx, maxx), randRange(rand, miny, maxy), 89 randRange(rand, minx, maxx), randRange(rand, miny, maxy), 90 paint); 91 } 92 } 93 94 static void show_hair(SkCanvas* canvas, bool doAA) { 95 show_stroke(canvas, doAA, 0, 150); 96 } 97 98 static void show_thick(SkCanvas* canvas, bool doAA) { 99 show_stroke(canvas, doAA, SkIntToScalar(5), 50); 100 } 101 102 typedef void (*CanvasProc)(SkCanvas*, bool); 103 104 class ClipView : public Sample { 105 public: 106 ClipView() { 107 SkAAClip clip; 108 SkIRect r = { -2, -3, 842, 18 }; 109 clip.setRect(r); 110 } 111 112 virtual ~ClipView() { 113 } 114 115 protected: 116 virtual bool onQuery(Sample::Event* evt) { 117 if (Sample::TitleQ(*evt)) { 118 Sample::TitleR(evt, "Clip"); 119 return true; 120 } 121 return this->INHERITED::onQuery(evt); 122 } 123 124 virtual void onDrawContent(SkCanvas* canvas) { 125 canvas->drawColor(SK_ColorWHITE); 126 canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); 127 128 static const CanvasProc gProc[] = { 129 show_text, show_thick, show_hair, show_fill 130 }; 131 132 SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) }; 133 SkPath clipPath; 134 r.inset(SK_Scalar1 / 4, SK_Scalar1 / 4); 135 clipPath.addRoundRect(r, SkIntToScalar(20), SkIntToScalar(20)); 136 137 // clipPath.toggleInverseFillType(); 138 139 for (int aa = 0; aa <= 1; ++aa) { 140 canvas->save(); 141 for (size_t i = 0; i < SK_ARRAY_COUNT(gProc); ++i) { 142 canvas->save(); 143 canvas->clipPath(clipPath, kIntersect_SkClipOp, SkToBool(aa)); 144 // canvas->drawColor(SK_ColorWHITE); 145 gProc[i](canvas, SkToBool(aa)); 146 canvas->restore(); 147 canvas->translate(W * SK_Scalar1 * 8 / 7, 0); 148 } 149 canvas->restore(); 150 canvas->translate(0, H * SK_Scalar1 * 8 / 7); 151 } 152 } 153 154 private: 155 typedef Sample INHERITED; 156 }; 157 158 ////////////////////////////////////////////////////////////////////////////// 159 160 DEF_SAMPLE( return new ClipView(); ) 161