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 "SkPath.h" 10#include "SkRandom.h" 11#include "SkRRect.h" 12 13namespace skiagm { 14 15// Test out various combinations of nested rects, ovals and rrects. 16class NestedGM : public GM { 17public: 18 NestedGM(bool doAA, bool flipped) : fDoAA(doAA), fFlipped(flipped) { 19 this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD)); 20 } 21 22protected: 23 24 SkString onShortName() override { 25 SkString name("nested"); 26 if (fFlipped) { 27 name.append("_flipY"); 28 } 29 if (fDoAA) { 30 name.append("_aa"); 31 } else { 32 name.append("_bw"); 33 } 34 return name; 35 } 36 37 SkISize onISize() override { 38 return SkISize::Make(kImageWidth, kImageHeight); 39 } 40 41 enum Shapes { 42 kRect_Shape = 0, 43 kRRect_Shape, 44 kOval_Shape, 45 kShapeCount 46 }; 47 48 static void AddShape(SkPath* path, const SkRect& rect, Shapes shape, SkPath::Direction dir) { 49 switch (shape) { 50 case kRect_Shape: 51 path->addRect(rect, dir); 52 break; 53 case kRRect_Shape: { 54 SkRRect rr; 55 rr.setRectXY(rect, 5, 5); 56 path->addRRect(rr, dir); 57 break; 58 } 59 case kOval_Shape: 60 path->addOval(rect, dir); 61 break; 62 default: 63 break; 64 } 65 } 66 67 void onDraw(SkCanvas* canvas) override { 68 69 SkPaint shapePaint; 70 shapePaint.setColor(SK_ColorBLACK); 71 shapePaint.setAntiAlias(fDoAA); 72 73 SkRect outerRect = SkRect::MakeWH(40, 40); 74 75 SkRect innerRects[] = { 76 { 10, 10, 30, 30 }, // small 77 { .5f, 18, 4.5f, 22 } // smaller and offset to left 78 }; 79 80 // draw a background pattern to make transparency errors more apparent 81 SkRandom rand; 82 83 for (int y = 0; y < kImageHeight; y += 10) { 84 for (int x = 0; x < kImageWidth; x += 10) { 85 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x), 86 SkIntToScalar(y), 87 10, 10); 88 SkPaint p; 89 p.setColor(rand.nextU() | 0xFF000000); 90 canvas->drawRect(r, p); 91 } 92 } 93 94 SkScalar xOff = 2, yOff = 2; 95 for (int outerShape = 0; outerShape < kShapeCount; ++outerShape) { 96 for (int innerShape = 0; innerShape < kShapeCount; ++innerShape) { 97 for (size_t innerRect = 0; innerRect < SK_ARRAY_COUNT(innerRects); ++innerRect) { 98 SkPath path; 99 100 AddShape(&path, outerRect, (Shapes) outerShape, SkPath::kCW_Direction); 101 AddShape(&path, innerRects[innerRect], (Shapes) innerShape, 102 SkPath::kCCW_Direction); 103 104 canvas->save(); 105 if (fFlipped) { 106 canvas->scale(1.0f, -1.0f); 107 canvas->translate(xOff, -yOff - 40.0f); 108 } else { 109 canvas->translate(xOff, yOff); 110 } 111 112 canvas->drawPath(path, shapePaint); 113 canvas->restore(); 114 115 xOff += 45; 116 } 117 } 118 119 xOff = 2; 120 yOff += 45; 121 } 122 123 } 124 125private: 126 static const int kImageWidth = 269; 127 static const int kImageHeight = 134; 128 129 bool fDoAA; 130 bool fFlipped; 131 132 typedef GM INHERITED; 133}; 134 135/////////////////////////////////////////////////////////////////////////////// 136 137DEF_GM( return new NestedGM(/* doAA = */ true, /* flipped = */ false); ) 138DEF_GM( return new NestedGM(/* doAA = */ false, /* flipped = */ false); ) 139DEF_GM( return new NestedGM(/* doAA = */ true, /* flipped = */ true); ) 140DEF_GM( return new NestedGM(/* doAA = */ false, /* flipped = */ true); ) 141 142} 143