| /* | 
 |  * Copyright 2013 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "gm.h" | 
 | #include "SkCanvas.h" | 
 | #include "SkPath.h" | 
 | #include "SkDashPathEffect.h" | 
 |  | 
 | static SkPath generate_square(SkScalar cx, SkScalar cy, SkScalar w) { | 
 |     SkRect rect = SkRect::MakeXYWH(cx - w / 2, cy - w / 2, w, w); | 
 |     SkPath path; | 
 |     path.addRect(rect); | 
 |     return path; | 
 | } | 
 |  | 
 | static SkPath generate_rect_line(SkScalar cx, SkScalar cy, SkScalar l) { | 
 |     SkRect rect = SkRect::MakeXYWH(cx - l / 2, cy, l, 0); | 
 |     SkPath path; | 
 |     path.addRect(rect); | 
 |     return path; | 
 | } | 
 |  | 
 | static SkPath generate_circle(SkScalar cx, SkScalar cy, SkScalar d) { | 
 |     SkPath path; | 
 |     path.addCircle(cx, cy, d/2, SkPath::kCW_Direction); | 
 |     return path; | 
 | } | 
 |  | 
 | static SkPath generate_line(SkScalar cx, SkScalar cy, SkScalar l) { | 
 |     SkPath path; | 
 |     path.moveTo(cx - l / 2, cy); | 
 |     path.lineTo(cx + l / 2, cy); | 
 |     return path; | 
 | } | 
 |  | 
 | namespace { | 
 | struct Style { | 
 |     Style(SkPaint::Style paintStyle, sk_sp<SkPathEffect> pe = sk_sp<SkPathEffect>()) | 
 |         : fPaintStyle(paintStyle) | 
 |         , fPathEffect(std::move(pe)) {} | 
 |     SkPaint::Style      fPaintStyle; | 
 |     sk_sp<SkPathEffect> fPathEffect; | 
 | }; | 
 |  | 
 | sk_sp<SkPathEffect> make_dash() { | 
 |     constexpr SkScalar kIntervals[] = { 4.f, 3.f }; | 
 |     return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), 0); | 
 | } | 
 |  | 
 | Style styles[] { | 
 |     {SkPaint::kStroke_Style}, | 
 |     {SkPaint::kStrokeAndFill_Style}, | 
 |     {SkPaint::kFill_Style}, | 
 |     {SkPaint::kStroke_Style, make_dash()}, | 
 | }; | 
 |  | 
 | SkScalar pathSizes[] = { | 
 |         40, | 
 |         10, | 
 |         0 | 
 | }; | 
 | SkScalar strokeWidths[] = { | 
 |         10, | 
 |         0 | 
 | }; | 
 | SkPath ((*paths[])(SkScalar, SkScalar, SkScalar)) = { | 
 |         generate_square, | 
 |         generate_rect_line, | 
 |         generate_circle, | 
 |         generate_line | 
 | }; | 
 |  | 
 | const SkScalar slideWidth = 90, slideHeight = 90; | 
 | const SkScalar slideBoundary = 5; | 
 |  | 
 | }  // namespace | 
 |  | 
 | DEF_SIMPLE_GM(inverse_paths, canvas, 800, 1200) { | 
 |     SkScalar cx = slideWidth / 2 + slideBoundary; | 
 |     SkScalar cy = slideHeight / 2 + slideBoundary; | 
 |     SkScalar dx = slideWidth + 2 * slideBoundary; | 
 |     SkScalar dy = slideHeight + 2 * slideBoundary; | 
 |  | 
 |     SkRect clipRect = SkRect::MakeLTRB(slideBoundary, slideBoundary, | 
 |                                        slideBoundary + slideWidth, | 
 |                                        slideBoundary + slideHeight); | 
 |     SkPaint clipPaint; | 
 |     clipPaint.setStyle(SkPaint::kStroke_Style); | 
 |     clipPaint.setStrokeWidth(SkIntToScalar(2)); | 
 |  | 
 |     SkPaint outlinePaint; | 
 |     outlinePaint.setColor(0x40000000); | 
 |     outlinePaint.setStyle(SkPaint::kStroke_Style); | 
 |     outlinePaint.setStrokeWidth(SkIntToScalar(0)); | 
 |  | 
 |     for (size_t styleIndex = 0; styleIndex < SK_ARRAY_COUNT(styles); | 
 |             styleIndex++) { | 
 |         for (size_t sizeIndex = 0; sizeIndex < SK_ARRAY_COUNT(pathSizes); | 
 |                 sizeIndex++) { | 
 |             SkScalar size = pathSizes[sizeIndex]; | 
 |  | 
 |             canvas->save(); | 
 |  | 
 |             for (size_t widthIndex = 0; | 
 |                     widthIndex < SK_ARRAY_COUNT(strokeWidths); | 
 |                     widthIndex++) { | 
 |                 SkPaint paint; | 
 |                 paint.setColor(0xff007000); | 
 |                 paint.setStrokeWidth(strokeWidths[widthIndex]); | 
 |                 paint.setStyle(styles[styleIndex].fPaintStyle); | 
 |                 paint.setPathEffect(styles[styleIndex].fPathEffect); | 
 |  | 
 |                 for (size_t pathIndex = 0; | 
 |                         pathIndex < SK_ARRAY_COUNT(paths); | 
 |                         pathIndex++) { | 
 |                     canvas->drawRect(clipRect, clipPaint); | 
 |  | 
 |                     canvas->save(); | 
 |                     canvas->clipRect(clipRect); | 
 |  | 
 |                     SkPath path = paths[pathIndex](cx, cy, size); | 
 |                     path.setFillType(SkPath::kInverseWinding_FillType); | 
 |                     canvas->drawPath(path, paint); | 
 |  | 
 |                     path.setFillType(SkPath::kWinding_FillType); | 
 |                     canvas->drawPath(path, outlinePaint); | 
 |  | 
 |                     canvas->restore(); | 
 |                     canvas->translate(dx, 0); | 
 |                 } | 
 |             } | 
 |             canvas->restore(); | 
 |             canvas->translate(0, dy); | 
 |         } | 
 |     } | 
 | } |