1 /* 2 * Copyright 2015 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 11 typedef SkScalar (*MakePathProc)(SkPath*); 12 13 static SkScalar make_triangle(SkPath* path) { 14 constexpr int gCoord[] = { 15 10, 20, 15, 5, 30, 30 16 }; 17 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1])); 18 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3])); 19 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5])); 20 path->close(); 21 path->offset(SkIntToScalar(10), SkIntToScalar(0)); 22 return SkIntToScalar(30); 23 } 24 25 static SkScalar make_rect(SkPath* path) { 26 SkRect r = { SkIntToScalar(10), SkIntToScalar(10), 27 SkIntToScalar(30), SkIntToScalar(30) }; 28 path->addRect(r); 29 path->offset(SkIntToScalar(10), SkIntToScalar(0)); 30 return SkIntToScalar(30); 31 } 32 33 static SkScalar make_oval(SkPath* path) { 34 SkRect r = { SkIntToScalar(10), SkIntToScalar(10), 35 SkIntToScalar(30), SkIntToScalar(30) }; 36 path->addOval(r); 37 path->offset(SkIntToScalar(10), SkIntToScalar(0)); 38 return SkIntToScalar(30); 39 } 40 41 static SkScalar make_star(SkPath* path, int n) { 42 const SkScalar c = SkIntToScalar(45); 43 const SkScalar r = SkIntToScalar(20); 44 45 SkScalar rad = -SK_ScalarPI / 2; 46 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n; 47 48 path->moveTo(c, c - r); 49 for (int i = 1; i < n; i++) { 50 rad += drad; 51 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV); 52 path->lineTo(c + cosV * r, c + sinV * r); 53 } 54 path->close(); 55 return r * 2 * 6 / 5; 56 } 57 58 static SkScalar make_star_5(SkPath* path) { return make_star(path, 5); } 59 static SkScalar make_star_13(SkPath* path) { return make_star(path, 13); } 60 61 static SkScalar make_three_line(SkPath* path) { 62 static SkScalar xOffset = 34.f; 63 static SkScalar yOffset = 50.f; 64 path->moveTo(-32.5f + xOffset, 0.0f + yOffset); 65 path->lineTo(32.5f + xOffset, 0.0f + yOffset); 66 67 path->moveTo(-32.5f + xOffset, 19 + yOffset); 68 path->lineTo(32.5f + xOffset, 19 + yOffset); 69 70 path->moveTo(-32.5f + xOffset, -19 + yOffset); 71 path->lineTo(32.5f + xOffset, -19 + yOffset); 72 path->lineTo(-32.5f + xOffset, -19 + yOffset); 73 74 path->close(); 75 76 return SkIntToScalar(70); 77 } 78 79 static SkScalar make_arrow(SkPath* path) { 80 static SkScalar xOffset = 34.f; 81 static SkScalar yOffset = 40.f; 82 path->moveTo(-26.f + xOffset, 0.0f + yOffset); 83 path->lineTo(26.f + xOffset, 0.0f + yOffset); 84 85 path->moveTo(-28.f + xOffset, -2.4748745f + yOffset); 86 path->lineTo(0 + xOffset, 25.525126f + yOffset); 87 88 path->moveTo(-28.f + xOffset, 2.4748745f + yOffset); 89 path->lineTo(0 + xOffset, -25.525126f + yOffset); 90 path->lineTo(-28.f + xOffset, 2.4748745f + yOffset); 91 92 path->close(); 93 94 return SkIntToScalar(70); 95 } 96 97 static SkScalar make_curve(SkPath* path) { 98 static SkScalar xOffset = -382.f; 99 static SkScalar yOffset = -50.f; 100 path->moveTo(491 + xOffset, 56 + yOffset); 101 path->conicTo(435.93292f + xOffset, 56.000031f + yOffset, 102 382.61078f + xOffset, 69.752716f + yOffset, 103 0.9920463f); 104 105 return SkIntToScalar(40); 106 } 107 108 static SkScalar make_battery(SkPath* path) { 109 static SkScalar xOffset = 5.0f; 110 111 path->moveTo(24.67f + xOffset, 0.33000004f); 112 path->lineTo(8.3299999f + xOffset, 0.33000004f); 113 path->lineTo(8.3299999f + xOffset, 5.3299999f); 114 path->lineTo(0.33000004f + xOffset, 5.3299999f); 115 path->lineTo(0.33000004f + xOffset, 50.669998f); 116 path->lineTo(32.669998f + xOffset, 50.669998f); 117 path->lineTo(32.669998f + xOffset, 5.3299999f); 118 path->lineTo(24.67f + xOffset, 5.3299999f); 119 path->lineTo(24.67f + xOffset, 0.33000004f); 120 path->close(); 121 122 path->moveTo(25.727224f + xOffset, 12.886665f); 123 path->lineTo(10.907918f + xOffset, 12.886665f); 124 path->lineTo(7.5166659f + xOffset, 28.683645f); 125 path->lineTo(14.810181f + xOffset, 28.683645f); 126 path->lineTo(7.7024879f + xOffset, 46.135998f); 127 path->lineTo(28.049999f + xOffset, 25.136419f); 128 path->lineTo(16.854223f + xOffset, 25.136419f); 129 path->lineTo(25.727224f + xOffset, 12.886665f); 130 path->close(); 131 return SkIntToScalar(50); 132 } 133 134 static SkScalar make_battery2(SkPath* path) { 135 static SkScalar xOffset = 225.625f; 136 137 path->moveTo(32.669998f + xOffset, 9.8640003f); 138 path->lineTo(0.33000004f + xOffset, 9.8640003f); 139 path->lineTo(0.33000004f + xOffset, 50.669998f); 140 path->lineTo(32.669998f + xOffset, 50.669998f); 141 path->lineTo(32.669998f + xOffset, 9.8640003f); 142 path->close(); 143 144 path->moveTo(10.907918f + xOffset, 12.886665f); 145 path->lineTo(25.727224f + xOffset, 12.886665f); 146 path->lineTo(16.854223f + xOffset, 25.136419f); 147 path->lineTo(28.049999f + xOffset, 25.136419f); 148 path->lineTo(7.7024879f + xOffset, 46.135998f); 149 path->lineTo(14.810181f + xOffset, 28.683645f); 150 path->lineTo(7.5166659f + xOffset, 28.683645f); 151 path->lineTo(10.907918f + xOffset, 12.886665f); 152 path->close(); 153 154 return SkIntToScalar(70); 155 } 156 157 constexpr MakePathProc gProcs[] = { 158 make_triangle, 159 make_rect, 160 make_oval, 161 make_star_5, 162 make_star_13, 163 make_three_line, 164 make_arrow, 165 make_curve, 166 make_battery, 167 make_battery2 168 }; 169 170 constexpr SkScalar gWidths[] = { 171 2.0f, 172 3.0f, 173 4.0f, 174 5.0f, 175 6.0f, 176 7.0f, 177 7.0f, 178 14.0f, 179 0.0f, 180 0.0f, 181 }; 182 183 constexpr SkScalar gMiters[] = { 184 2.0f, 185 3.0f, 186 3.0f, 187 3.0f, 188 4.0f, 189 4.0f, 190 4.0f, 191 4.0f, 192 4.0f, 193 4.0f, 194 }; 195 196 constexpr SkScalar gXTranslate[] = { 197 0.0f, 198 0.0f, 199 0.0f, 200 0.0f, 201 0.0f, 202 0.0f, 203 0.0f, 204 0.0f, 205 -220.625f, 206 0.0f, 207 }; 208 209 #define N SK_ARRAY_COUNT(gProcs) 210 211 // This GM tests out drawing small paths (i.e., for Ganesh, using the Distance 212 // Field path renderer) which are filled, stroked and filledAndStroked. In 213 // particular this ensures that any cache keys in use include the stroking 214 // parameters. 215 class SmallPathsGM : public skiagm::GM { 216 SkPath fPath[N]; 217 SkScalar fDY[N]; 218 protected: 219 void onOnceBeforeDraw() override { 220 for (size_t i = 0; i < N; i++) { 221 fDY[i] = gProcs[i](&fPath[i]); 222 } 223 } 224 225 SkString onShortName() override { 226 return SkString("smallpaths"); 227 } 228 229 SkISize onISize() override { 230 return SkISize::Make(640, 480); 231 } 232 233 void onDraw(SkCanvas* canvas) override { 234 SkPaint paint; 235 paint.setAntiAlias(true); 236 237 // first column: filled paths 238 canvas->save(); 239 for (size_t i = 0; i < N; i++) { 240 canvas->drawPath(fPath[i], paint); 241 canvas->translate(gXTranslate[i], fDY[i]); 242 } 243 canvas->restore(); 244 canvas->translate(SkIntToScalar(120), SkIntToScalar(0)); 245 246 // second column: stroked paths 247 canvas->save(); 248 paint.setStyle(SkPaint::kStroke_Style); 249 paint.setStrokeCap(SkPaint::kButt_Cap); 250 for (size_t i = 0; i < N; i++) { 251 paint.setStrokeWidth(gWidths[i]); 252 paint.setStrokeMiter(gMiters[i]); 253 canvas->drawPath(fPath[i], paint); 254 canvas->translate(gXTranslate[i], fDY[i]); 255 } 256 canvas->restore(); 257 canvas->translate(SkIntToScalar(120), SkIntToScalar(0)); 258 259 // third column: stroked paths with different widths 260 canvas->save(); 261 paint.setStyle(SkPaint::kStroke_Style); 262 paint.setStrokeCap(SkPaint::kButt_Cap); 263 for (size_t i = 0; i < N; i++) { 264 paint.setStrokeWidth(gWidths[i] + 2.0f); 265 paint.setStrokeMiter(gMiters[i]); 266 canvas->drawPath(fPath[i], paint); 267 canvas->translate(gXTranslate[i], fDY[i]); 268 } 269 canvas->restore(); 270 canvas->translate(SkIntToScalar(120), SkIntToScalar(0)); 271 272 // fourth column: stroked and filled paths 273 paint.setStyle(SkPaint::kStrokeAndFill_Style); 274 paint.setStrokeCap(SkPaint::kButt_Cap); 275 for (size_t i = 0; i < N; i++) { 276 paint.setStrokeWidth(gWidths[i]); 277 paint.setStrokeMiter(gMiters[i]); 278 canvas->drawPath(fPath[i], paint); 279 canvas->translate(gXTranslate[i], fDY[i]); 280 } 281 282 } 283 284 private: 285 typedef skiagm::GM INHERITED; 286 }; 287 288 DEF_GM(return new SmallPathsGM;) 289