inversepaths.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright 2013 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. #include "gm/gm.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkPaint.h"
  10. #include "include/core/SkPath.h"
  11. #include "include/core/SkPathEffect.h"
  12. #include "include/core/SkRect.h"
  13. #include "include/core/SkRefCnt.h"
  14. #include "include/core/SkScalar.h"
  15. #include "include/core/SkTypes.h"
  16. #include "include/effects/SkDashPathEffect.h"
  17. #include <utility>
  18. static SkPath generate_square(SkScalar cx, SkScalar cy, SkScalar w) {
  19. SkRect rect = SkRect::MakeXYWH(cx - w / 2, cy - w / 2, w, w);
  20. SkPath path;
  21. path.addRect(rect);
  22. return path;
  23. }
  24. static SkPath generate_rect_line(SkScalar cx, SkScalar cy, SkScalar l) {
  25. SkRect rect = SkRect::MakeXYWH(cx - l / 2, cy, l, 0);
  26. SkPath path;
  27. path.addRect(rect);
  28. return path;
  29. }
  30. static SkPath generate_circle(SkScalar cx, SkScalar cy, SkScalar d) {
  31. SkPath path;
  32. path.addCircle(cx, cy, d/2, SkPath::kCW_Direction);
  33. return path;
  34. }
  35. static SkPath generate_line(SkScalar cx, SkScalar cy, SkScalar l) {
  36. SkPath path;
  37. path.moveTo(cx - l / 2, cy);
  38. path.lineTo(cx + l / 2, cy);
  39. return path;
  40. }
  41. namespace {
  42. struct Style {
  43. Style(SkPaint::Style paintStyle, sk_sp<SkPathEffect> pe = sk_sp<SkPathEffect>())
  44. : fPaintStyle(paintStyle)
  45. , fPathEffect(std::move(pe)) {}
  46. SkPaint::Style fPaintStyle;
  47. sk_sp<SkPathEffect> fPathEffect;
  48. };
  49. sk_sp<SkPathEffect> make_dash() {
  50. constexpr SkScalar kIntervals[] = { 4.f, 3.f };
  51. return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), 0);
  52. }
  53. Style styles[] {
  54. {SkPaint::kStroke_Style},
  55. {SkPaint::kStrokeAndFill_Style},
  56. {SkPaint::kFill_Style},
  57. {SkPaint::kStroke_Style, make_dash()},
  58. };
  59. SkScalar pathSizes[] = {
  60. 40,
  61. 10,
  62. 0
  63. };
  64. SkScalar strokeWidths[] = {
  65. 10,
  66. 0
  67. };
  68. SkPath (*paths[])(SkScalar, SkScalar, SkScalar) = {
  69. generate_square,
  70. generate_rect_line,
  71. generate_circle,
  72. generate_line
  73. };
  74. const SkScalar slideWidth = 90, slideHeight = 90;
  75. const SkScalar slideBoundary = 5;
  76. } // namespace
  77. DEF_SIMPLE_GM(inverse_paths, canvas, 800, 1200) {
  78. SkScalar cx = slideWidth / 2 + slideBoundary;
  79. SkScalar cy = slideHeight / 2 + slideBoundary;
  80. SkScalar dx = slideWidth + 2 * slideBoundary;
  81. SkScalar dy = slideHeight + 2 * slideBoundary;
  82. SkRect clipRect = SkRect::MakeLTRB(slideBoundary, slideBoundary,
  83. slideBoundary + slideWidth,
  84. slideBoundary + slideHeight);
  85. SkPaint clipPaint;
  86. clipPaint.setStyle(SkPaint::kStroke_Style);
  87. clipPaint.setStrokeWidth(SkIntToScalar(2));
  88. SkPaint outlinePaint;
  89. outlinePaint.setColor(0x40000000);
  90. outlinePaint.setStyle(SkPaint::kStroke_Style);
  91. outlinePaint.setStrokeWidth(SkIntToScalar(0));
  92. for (size_t styleIndex = 0; styleIndex < SK_ARRAY_COUNT(styles);
  93. styleIndex++) {
  94. for (size_t sizeIndex = 0; sizeIndex < SK_ARRAY_COUNT(pathSizes);
  95. sizeIndex++) {
  96. SkScalar size = pathSizes[sizeIndex];
  97. canvas->save();
  98. for (size_t widthIndex = 0;
  99. widthIndex < SK_ARRAY_COUNT(strokeWidths);
  100. widthIndex++) {
  101. SkPaint paint;
  102. paint.setColor(0xff007000);
  103. paint.setStrokeWidth(strokeWidths[widthIndex]);
  104. paint.setStyle(styles[styleIndex].fPaintStyle);
  105. paint.setPathEffect(styles[styleIndex].fPathEffect);
  106. for (size_t pathIndex = 0;
  107. pathIndex < SK_ARRAY_COUNT(paths);
  108. pathIndex++) {
  109. canvas->drawRect(clipRect, clipPaint);
  110. canvas->save();
  111. canvas->clipRect(clipRect);
  112. SkPath path = paths[pathIndex](cx, cy, size);
  113. path.setFillType(SkPath::kInverseWinding_FillType);
  114. canvas->drawPath(path, paint);
  115. path.setFillType(SkPath::kWinding_FillType);
  116. canvas->drawPath(path, outlinePaint);
  117. canvas->restore();
  118. canvas->translate(dx, 0);
  119. }
  120. }
  121. canvas->restore();
  122. canvas->translate(0, dy);
  123. }
  124. }
  125. }