| /* |
| * 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); |
| } |
| } |
| } |