1 /* 2 * Copyright 2012 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 "sk_tool_utils.h" 10 #include "SkCanvas.h" 11 #include "SkPath.h" 12 13 #define STROKE_WIDTH SkIntToScalar(20) 14 15 static void draw_path(SkCanvas* canvas, const SkPath& path, const SkRect& rect, 16 SkPaint::Join join, int doFill) { 17 SkPaint paint; 18 paint.setAntiAlias(true); 19 paint.setStyle(doFill ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style); 20 21 paint.setColor(sk_tool_utils::color_to_565(SK_ColorGRAY)); 22 paint.setStrokeWidth(STROKE_WIDTH); 23 paint.setStrokeJoin(join); 24 canvas->drawRect(rect, paint); 25 26 paint.setStyle(SkPaint::kStroke_Style); 27 paint.setStrokeWidth(0); 28 paint.setColor(SK_ColorRED); 29 canvas->drawPath(path, paint); 30 31 paint.setStrokeWidth(3); 32 paint.setStrokeJoin(SkPaint::kMiter_Join); 33 int n = path.countPoints(); 34 SkAutoTArray<SkPoint> points(n); 35 path.getPoints(points.get(), n); 36 canvas->drawPoints(SkCanvas::kPoints_PointMode, n, points.get(), paint); 37 } 38 39 /* 40 * Test calling SkStroker for rectangles. Cases to cover: 41 * 42 * geometry: normal, small (smaller than stroke-width), empty, inverted 43 * joint-type for the corners 44 */ 45 class StrokeRectGM : public skiagm::GM { 46 public: 47 StrokeRectGM() {} 48 49 protected: 50 51 SkString onShortName() override { 52 return SkString("strokerect"); 53 } 54 55 SkISize onISize() override { 56 return SkISize::Make(1400, 740); 57 } 58 59 void onDraw(SkCanvas* canvas) override { 60 canvas->drawColor(SK_ColorWHITE); 61 canvas->translate(STROKE_WIDTH*3/2, STROKE_WIDTH*3/2); 62 63 SkPaint paint; 64 paint.setStyle(SkPaint::kStroke_Style); 65 paint.setStrokeWidth(STROKE_WIDTH); 66 67 constexpr SkPaint::Join gJoins[] = { 68 SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join 69 }; 70 71 constexpr SkScalar W = 80; 72 constexpr SkScalar H = 80; 73 constexpr SkRect gRects[] = { 74 { 0, 0, W, H }, 75 { W, 0, 0, H }, 76 { 0, H, W, 0 }, 77 { 0, 0, STROKE_WIDTH, H }, 78 { 0, 0, W, STROKE_WIDTH }, 79 { 0, 0, STROKE_WIDTH/2, STROKE_WIDTH/2 }, 80 { 0, 0, W, 0 }, 81 { 0, 0, 0, H }, 82 { 0, 0, 0, 0 }, 83 { 0, 0, W, FLT_EPSILON }, 84 { 0, 0, FLT_EPSILON, H }, 85 { 0, 0, FLT_EPSILON, FLT_EPSILON }, 86 }; 87 88 for (int doFill = 0; doFill <= 1; ++doFill) { 89 for (size_t i = 0; i < SK_ARRAY_COUNT(gJoins); ++i) { 90 SkPaint::Join join = gJoins[i]; 91 paint.setStrokeJoin(join); 92 93 SkAutoCanvasRestore acr(canvas, true); 94 for (size_t j = 0; j < SK_ARRAY_COUNT(gRects); ++j) { 95 const SkRect& r = gRects[j]; 96 97 SkPath path, fillPath; 98 path.addRect(r); 99 paint.getFillPath(path, &fillPath); 100 draw_path(canvas, fillPath, r, join, doFill); 101 102 canvas->translate(W + 2 * STROKE_WIDTH, 0); 103 } 104 acr.restore(); 105 canvas->translate(0, H + 2 * STROKE_WIDTH); 106 } 107 paint.setStyle(SkPaint::kStrokeAndFill_Style); 108 } 109 } 110 111 private: 112 typedef GM INHERITED; 113 }; 114 DEF_GM(return new StrokeRectGM;) 115 116 /////////////////////////////////////////////////////////////////////////////////////////////////// 117 118 /* 119 * Exercise rect-stroking (which is specialized from paths) when the resulting stroke-width is 120 * non-square. See https://bugs.chromium.org/p/skia/issues/detail?id=5408 121 */ 122 DEF_SIMPLE_GM(strokerect_anisotropic_5408, canvas, 200, 50) { 123 SkPaint p; 124 p.setStyle(SkPaint::kStroke_Style); 125 p.setStrokeWidth(6); 126 127 canvas->scale(10, 1); 128 SkRect r = SkRect::MakeXYWH(5, 20, 10, 10); 129 canvas->drawRect(r, p); 130 } 131