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 DEF_SIMPLE_GM(analytic_antialias_convex, canvas, W, H) { 16 SkPaint p; 17 p.setColor(SK_ColorRED); 18 p.setAntiAlias(true); 19 20 canvas->clear(0xFFFFFFFF); 21 22 canvas->save(); 23 24 SkScalar y = 0; 25 26 canvas->translate(0, y); 27 canvas->rotate(1); 28 canvas->drawRect({ 20, 20, 200, 200 }, p); 29 canvas->restore(); 30 31 y += 200; 32 33 canvas->save(); 34 canvas->translate(0, y); 35 canvas->rotate(1); 36 canvas->drawRect({ 20, 20, 20.2f, 200 }, p); 37 canvas->drawRect({ 20, 200, 200, 200.1f }, p); 38 canvas->drawCircle(100, 100, 30, p); 39 canvas->restore(); 40 41 // The following path is empty but it'll reveal bug chrome:662914 42 SkPath path; 43 path.moveTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 44 // 77.8075f, 231.626f, 77.8074f, 231.625f, 77.8073f, 231.625f 45 path.cubicTo(SkBits2Float(0x429b9d71), SkBits2Float(0x4367a022), 46 SkBits2Float(0x429b9d64), SkBits2Float(0x4367a009), 47 SkBits2Float(0x429b9d50), SkBits2Float(0x43679ff2)); 48 path.lineTo(SkBits2Float(0x429b9d5c), SkBits2Float(0x4367a041)); // 77.8073f, 231.626f 49 path.close(); 50 canvas->drawPath(path, p); 51 52 // The following path reveals a subtle SkAnalyticQuadraticEdge::updateQuadratic bug: 53 // we should not use any snapped y for the intermediate values whose error may accumulate; 54 // snapping should only be allowed once before updateLine. 55 path.reset(); 56 path.moveTo(SkBits2Float(0x434ba71e), SkBits2Float(0x438a06d0)); // 203.653f, 276.053f 57 path.lineTo(SkBits2Float(0x43492a74), SkBits2Float(0x4396d70d)); // 201.166f, 301.68f 58 // 200.921f, 304.207f, 196.939f, 303.82f, 0.707107f 59 path.conicTo(SkBits2Float(0x4348ebaf), SkBits2Float(0x43981a75), 60 SkBits2Float(0x4344f079), SkBits2Float(0x4397e900), SkBits2Float(0x3f3504f3)); 61 path.close(); 62 // Manually setting convexity is required. Otherwise, this path will be considered concave. 63 path.setConvexity(SkPath::kConvex_Convexity); 64 canvas->drawPath(path, p); 65 66 // skbug.com/7573 67 y += 200; 68 canvas->save(); 69 canvas->translate(0, y); 70 p.setAntiAlias(true); 71 path.reset(); 72 path.moveTo(1.98009784f, 9.0162744f); 73 path.lineTo(47.843992f, 10.1922744f); 74 path.lineTo(47.804008f, 11.7597256f); 75 path.lineTo(1.93990216f, 10.5837256f); 76 canvas->drawPath(path, p); 77 canvas->restore(); 78 79 // skbug.com/7813 80 // t8888 splits the 800-high canvas into 3 pieces; the boundary is close to 266 and 534 81 path.reset(); 82 path.moveTo(700, 266); 83 path.lineTo(710, 266); 84 path.lineTo(710, 534); 85 path.lineTo(700, 534); 86 canvas->drawPath(path, p); 87 } 88 89 DEF_SIMPLE_GM(analytic_antialias_general, canvas, W, H) { 90 SkPaint p; 91 p.setColor(SK_ColorRED); 92 p.setAntiAlias(true); 93 94 canvas->clear(0xFFFFFFFF); 95 96 canvas->save(); 97 canvas->rotate(1); 98 const SkScalar R = 115.2f, C = 128.0f; 99 SkPath path; 100 path.moveTo(C + R, C); 101 for (int i = 1; i < 8; ++i) { 102 SkScalar a = 2.6927937f * i; 103 SkScalar cosine; 104 SkScalar sine = SkScalarSinCos(a, &cosine); 105 path.lineTo(C + R * cosine, C + R * sine); 106 } 107 canvas->drawPath(path, p); 108 canvas->restore(); 109 110 canvas->save(); 111 canvas->translate(200, 0); 112 canvas->rotate(1); 113 p.setStyle(SkPaint::kStroke_Style); 114 p.setStrokeWidth(5); 115 canvas->drawPath(path, p); 116 canvas->restore(); 117 118 119 // The following two paths test if we correctly cumulates the alpha on the middle pixel 120 // column where the left rect and the right rect abut. 121 p.setStyle(SkPaint::kFill_Style); 122 canvas->translate(0, 300); 123 path.reset(); 124 path.addRect({20, 20, 100.4999f, 100}); 125 path.addRect({100.5001f, 20, 200, 100}); 126 canvas->drawPath(path, p); 127 128 canvas->translate(300, 0); 129 path.reset(); 130 path.addRect({20, 20, 100.1f, 100}); 131 path.addRect({100.9f, 20, 200, 100}); 132 canvas->drawPath(path, p); 133 } 134 135 DEF_SIMPLE_GM(analytic_antialias_inverse, canvas, W, H) { 136 SkPaint p; 137 p.setColor(SK_ColorRED); 138 p.setAntiAlias(true); 139 140 canvas->save(); 141 142 SkPath path; 143 path.addCircle(100, 100, 30); 144 path.setFillType(SkPath::kInverseWinding_FillType); 145 canvas->drawPath(path, p); 146 canvas->restore(); 147 } 148