1 /* 2 * Copyright 2014 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 "SkScan.h" 11 12 #define W 800 13 #define H 800 14 15 class AnalyticAntiAliasConvexGM : public skiagm::GM { 16 public: 17 AnalyticAntiAliasConvexGM() {} 18 19 protected: 20 21 SkString onShortName() override { 22 return SkString("analytic_antialias_convex"); 23 } 24 25 SkISize onISize() override { 26 return SkISize::Make(W, H); 27 } 28 29 void onDraw(SkCanvas* canvas) override { 30 SkPaint p; 31 p.setColor(SK_ColorRED); 32 p.setAntiAlias(true); 33 34 canvas->clear(0xFFFFFFFF); 35 36 canvas->save(); 37 38 SkScalar y = 0; 39 40 canvas->translate(0, y); 41 canvas->rotate(1); 42 canvas->drawRect({ 20, 20, 200, 200 }, p); 43 canvas->restore(); 44 45 y += 200; 46 47 canvas->translate(0, y); 48 canvas->rotate(1); 49 canvas->drawRect({ 20, 20, 20.2f, 200 }, p); 50 canvas->drawRect({ 20, 200, 200, 200.1f }, p); 51 canvas->drawCircle(100, 100, 30, p); 52 canvas->restore(); 53 54 // The following path is empty but it'll reveal bug chrome:662914 55 SkPath path; 56 path.moveTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 57 // 77.8075f, 231.626f, 77.8074f, 231.625f, 77.8073f, 231.625f 58 path.cubicTo(SkBits2Float(0x429b9d71), SkBits2Float(0x4367a022), 59 SkBits2Float(0x429b9d64), SkBits2Float(0x4367a009), 60 SkBits2Float(0x429b9d50), SkBits2Float(0x43679ff2)); 61 path.lineTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 62 path.close(); 63 canvas->drawPath(path, p); 64 65 // The following path reveals a subtle SkAnalyticQuadraticEdge::updateQuadratic bug: 66 // we should not use any snapped y for the intermediate values whose error may accumulate; 67 // snapping should only be allowed once before updateLine. 68 path.reset(); 69 path.moveTo(SkBits2Float(0x434ba71e), SkBits2Float(0x438a06d0)); // 203.653f, 276.053f 70 path.lineTo(SkBits2Float(0x43492a74), SkBits2Float(0x4396d70d)); // 201.166f, 301.68f 71 // 200.921f, 304.207f, 196.939f, 303.82f, 0.707107f 72 path.conicTo(SkBits2Float(0x4348ebaf), SkBits2Float(0x43981a75), 73 SkBits2Float(0x4344f079), SkBits2Float(0x4397e900), SkBits2Float(0x3f3504f3)); 74 path.close(); 75 // Manually setting convexity is required. Otherwise, this path will be considered concave. 76 path.setConvexity(SkPath::kConvex_Convexity); 77 canvas->drawPath(path, p); 78 } 79 80 private: 81 typedef skiagm::GM INHERITED; 82 }; 83 84 class AnalyticAntiAliasGeneralGM : public skiagm::GM { 85 public: 86 AnalyticAntiAliasGeneralGM() {} 87 88 protected: 89 90 SkString onShortName() override { 91 return SkString("analytic_antialias_general"); 92 } 93 94 SkISize onISize() override { 95 return SkISize::Make(W, H); 96 } 97 98 void onDraw(SkCanvas* canvas) override { 99 SkPaint p; 100 p.setColor(SK_ColorRED); 101 p.setAntiAlias(true); 102 103 canvas->clear(0xFFFFFFFF); 104 105 canvas->save(); 106 canvas->rotate(1); 107 const SkScalar R = 115.2f, C = 128.0f; 108 SkPath path; 109 path.moveTo(C + R, C); 110 for (int i = 1; i < 8; ++i) { 111 SkScalar a = 2.6927937f * i; 112 SkScalar cosine; 113 SkScalar sine = SkScalarSinCos(a, &cosine); 114 path.lineTo(C + R * cosine, C + R * sine); 115 } 116 canvas->drawPath(path, p); 117 canvas->restore(); 118 119 canvas->save(); 120 canvas->translate(200, 0); 121 canvas->rotate(1); 122 p.setStyle(SkPaint::kStroke_Style); 123 p.setStrokeWidth(5); 124 canvas->drawPath(path, p); 125 canvas->restore(); 126 } 127 128 private: 129 typedef skiagm::GM INHERITED; 130 }; 131 132 class AnalyticAntiAliasInverseGM : public skiagm::GM { 133 public: 134 AnalyticAntiAliasInverseGM() {} 135 136 protected: 137 138 SkString onShortName() override { 139 return SkString("analytic_antialias_inverse"); 140 } 141 142 SkISize onISize() override { 143 return SkISize::Make(W, H); 144 } 145 146 void onDraw(SkCanvas* canvas) override { 147 SkPaint p; 148 p.setColor(SK_ColorRED); 149 p.setAntiAlias(true); 150 151 canvas->save(); 152 153 SkPath path; 154 path.addCircle(100, 100, 30); 155 path.setFillType(SkPath::kInverseWinding_FillType); 156 canvas->drawPath(path, p); 157 canvas->restore(); 158 } 159 160 private: 161 typedef skiagm::GM INHERITED; 162 }; 163 164 DEF_GM( return new AnalyticAntiAliasConvexGM; ) 165 DEF_GM( return new AnalyticAntiAliasGeneralGM; ) 166 DEF_GM( return new AnalyticAntiAliasInverseGM; ) 167