add more docs/examples from named fiddles.
ignore offscreen, srgb, and animated fiddles for now.
Change-Id: I923131b684865698e6cda138b004930e11f504d5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/263713
Commit-Queue: Hal Canary <halcanary@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
diff --git a/docs/examples/BlendModes.cpp b/docs/examples/BlendModes.cpp
new file mode 100644
index 0000000..2ea9170
--- /dev/null
+++ b/docs/examples/BlendModes.cpp
@@ -0,0 +1,73 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(BlendModes, 256, 4352, false, 0) {
+void drawBG(SkCanvas* canvas) {
+ SkColor radColors[] = {0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF};
+ auto rad = SkGradientShader::MakeRadial(SkPoint::Make(128, 128), 128, radColors, nullptr, 3,
+ SkTileMode::kClamp);
+
+ SkMatrix rotMtx;
+ rotMtx.setRotate(-90, 128, 128);
+ SkColor sweepColors[] = {0xFFFF00FF, 0xFFFF0000, 0xFFFFFF00, 0xFF00FF00,
+ 0xFF00FFFF, 0xFF0000FF, 0xFFFF00FF};
+ auto sweep = SkGradientShader::MakeSweep(128, 128, sweepColors, nullptr, 7, 0, &rotMtx);
+
+ auto comp = SkShaders::Blend(SkBlendMode::kModulate, std::move(rad), std::move(sweep));
+ SkPaint p;
+ p.setShader(std::move(comp));
+
+ canvas->drawPaint(p);
+}
+
+void draw(SkCanvas* canvas) {
+ SkBlendMode blendModes[] = {
+ SkBlendMode::kDst,
+ SkBlendMode::kSrc,
+ SkBlendMode::kSrcOver,
+ SkBlendMode::kDstOver,
+ SkBlendMode::kSrcIn,
+ SkBlendMode::kDstIn,
+ SkBlendMode::kSrcOut,
+ SkBlendMode::kDstOut,
+ SkBlendMode::kSrcATop,
+ SkBlendMode::kDstATop,
+ SkBlendMode::kXor,
+ SkBlendMode::kPlus,
+ SkBlendMode::kModulate,
+ SkBlendMode::kScreen,
+ SkBlendMode::kOverlay,
+ SkBlendMode::kDarken,
+ SkBlendMode::kLighten,
+ };
+
+ SkPaint labelPaint;
+ labelPaint.setAntiAlias(true);
+ SkFont font(nullptr, 12);
+
+ for (auto mode : blendModes) {
+ SkPaint layerPaint;
+ layerPaint.setBlendMode(mode);
+
+ canvas->save();
+ canvas->clipRect(SkRect::MakeWH(256, 256));
+
+ drawBG(canvas);
+
+ canvas->saveLayer(nullptr, &layerPaint);
+ const SkScalar r = 80;
+ SkPaint discP;
+ discP.setAntiAlias(true);
+ discP.setBlendMode(SkBlendMode::kPlus);
+ discP.setColor(SK_ColorGREEN); canvas->drawCircle(128, r, r, discP);
+ discP.setColor(SK_ColorRED); canvas->drawCircle(r, 256 - r, r, discP);
+ discP.setColor(SK_ColorBLUE); canvas->drawCircle(256 - r, 256 - r, r, discP);
+ canvas->restore();
+
+ canvas->drawSimpleText(SkBlendMode_Name(mode), strlen(SkBlendMode_Name(mode)),
+ SkTextEncoding::kUTF8, 10, 10, font, labelPaint);
+ canvas->restore();
+ canvas->translate(0, 256);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/ChromeMDRefreshTab.cpp b/docs/examples/ChromeMDRefreshTab.cpp
new file mode 100644
index 0000000..5b31a00
--- /dev/null
+++ b/docs/examples/ChromeMDRefreshTab.cpp
@@ -0,0 +1,155 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(ChromeMDRefreshTab, 256, 256, false, 0) {
+SkPath GetBorderPath(float scale,
+ bool unscale_at_end,
+ bool extend_to_top,
+ float endcap_width,
+ const SkISize& size) {
+ // const float top = scale - 1;
+ const float right = size.fWidth * scale;
+ const float bottom = size.fHeight * scale;
+ const float scaled_endcap_radius = (endcap_width / 2) * scale;
+
+ SkPath path;
+ path.moveTo(0, bottom - 1);
+ // bottom left
+ path.arcTo(scaled_endcap_radius - 1, scaled_endcap_radius - 1, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCCW, scaled_endcap_radius - 1,
+ bottom - 1 - scaled_endcap_radius);
+ // path.rLineTo(0, -1);
+ // path.rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale,
+ // -1.5 * scale);
+ path.lineTo(scaled_endcap_radius - 1, scaled_endcap_radius + 1);
+ // path.lineTo((endcap_width - 2) * scale, top + 1.5 * scale);
+ // top left
+ path.arcTo(scaled_endcap_radius + 1, scaled_endcap_radius + 1, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCW, scaled_endcap_radius * 2, -1);
+
+ // if (extend_to_top) {
+ // Create the vertical extension by extending the side diagonals until
+ // they reach the top of the bounds.
+ // const float dy = 2.5 * scale - 1;
+ // const float dx = Tab::GetInverseDiagonalSlope() * dy;
+ // path.rLineTo(dx, -dy);
+ // path.lineTo(right - (endcap_width - 2) * scale - dx, 0);
+ // path.rLineTo(dx, dy);
+ //} else {
+ // path.rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale, 2 * scale,
+ // -1.5 * scale);
+ // path.lineTo(right - endcap_width * scale, top);
+ // path.rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale,
+ // 1.5 * scale);
+ //}
+ path.lineTo(right - scaled_endcap_radius * 2, -1);
+ // path.lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale);
+
+ // top right
+ path.arcTo(scaled_endcap_radius + 1, scaled_endcap_radius + 1, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCW, right - scaled_endcap_radius + 1,
+ scaled_endcap_radius + 1);
+ // path.arcTo(SkRect::MakeLTRB(right - 2 * scale, bottom - 1 - 1.5 * scale,
+ // right - 2 * scale + 4, bottom - 1 - 1.5 * scale + 4), 90, 90, true);
+ // path.rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale,
+ // 1.5 * scale);
+
+ path.lineTo(right - scaled_endcap_radius + 1, bottom - 1 - scaled_endcap_radius);
+ // path.rLineTo(0, 1);
+
+ // bottom right
+ path.arcTo(scaled_endcap_radius - 1, scaled_endcap_radius - 1, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCCW, right, bottom - 1);
+ path.close();
+
+ if (unscale_at_end && (scale != 1)) path.transform(SkMatrix::MakeScale(1.f / scale));
+
+ return path;
+}
+
+SkPath GetInteriorPath(
+ float scale, const SkISize& size, float endcap_width, float horizontal_inset = 0) {
+ const float right = size.fWidth * scale;
+ // The bottom of the tab needs to be pixel-aligned or else when we call
+ // ClipPath with anti-aliasing enabled it can cause artifacts.
+ const float bottom = std::ceil(size.fHeight * scale);
+
+ // const float scaled_horizontal_inset = horizontal_inset * scale;
+
+ const float scaled_endcap_radius = (endcap_width / 2) * scale;
+
+ // Construct the interior path by intersecting paths representing the left
+ // and right halves of the tab. Compared to computing the full path at once,
+ // this makes it easier to avoid overdraw in the top center near minimum
+ // width, and to implement cases where |horizontal_inset| != 0.
+ SkPath right_path;
+
+ right_path.moveTo(right, bottom);
+ // right_path.moveTo(right - 1 - scaled_horizontal_inset, bottom);
+
+ right_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCW, right - scaled_endcap_radius,
+ bottom - scaled_endcap_radius);
+ // right_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale,
+ // -2 * scale, -1.5 * scale);
+
+ right_path.lineTo(right - scaled_endcap_radius, scaled_endcap_radius);
+ // right_path.lineTo(
+ // right - 1 - scaled_horizontal_inset - (endcap_width - 2) * scale,
+ // 2.5 * scale);
+
+ right_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCCW, right - scaled_endcap_radius * 2, 0);
+ // right_path.rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale, -1.5 * scale,
+ // -2 * scale, -1.5 * scale);
+
+ right_path.lineTo(0, 0);
+ right_path.lineTo(0, bottom);
+ right_path.close();
+
+ SkPath left_path;
+ // const float scaled_endcap_width = 1 + endcap_width * scale;
+ left_path.moveTo(scaled_endcap_radius * 2, 0);
+ // left_path.moveTo(scaled_endcap_width + scaled_horizontal_inset, scale);
+
+ left_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCCW, scaled_endcap_radius, scaled_endcap_radius);
+ // left_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, 0.5 * scale, -2 * scale,
+ // 1.5 * scale);
+
+ left_path.lineTo(scaled_endcap_radius, bottom - scaled_endcap_radius);
+ // left_path.lineTo(1 + scaled_horizontal_inset + 2 * scale,
+ // bottom - 1.5 * scale);
+
+ left_path.arcTo(scaled_endcap_radius, scaled_endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCW, 0, bottom);
+ // left_path.rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale,
+ // -2 * scale, 1.5 * scale);
+
+ left_path.lineTo(right, bottom);
+ left_path.lineTo(right, 0);
+ left_path.close();
+
+ SkPath complete_path;
+ Op(left_path, right_path, SkPathOp::kIntersect_SkPathOp, &complete_path);
+ return complete_path;
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(1);
+ SkPath path = GetInteriorPath(1.f, SkISize::Make(250, 36), 16);
+ path.transform(SkMatrix::MakeTrans(0, 30));
+ canvas->drawPath(path, p);
+
+ p.setColor(SK_ColorBLUE);
+ SkPath border_path = GetBorderPath(1.f, false, false, 16, SkISize::Make(250, 36));
+ border_path.transform(SkMatrix::MakeTrans(0, 30));
+ canvas->drawPath(border_path, p);
+
+ // canvas->drawLine(20, 20, 100, 100, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/ChromeMDRefreshTabs.cpp b/docs/examples/ChromeMDRefreshTabs.cpp
new file mode 100644
index 0000000..8552ad9
--- /dev/null
+++ b/docs/examples/ChromeMDRefreshTabs.cpp
@@ -0,0 +1,83 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(ChromeMDRefreshTabs, 256, 256, false, 0) {
+SkPath GetInteriorPath(
+ float scale, const SkISize& size, float endcap_width, float horizontal_inset = 0) {
+ const float right = size.fWidth * scale;
+ // The bottom of the tab needs to be pixel-aligned or else when we call
+ // ClipPath with anti-aliasing enabled it can cause artifacts.
+ const float bottom = std::ceil(size.fHeight * scale);
+
+ // const float scaled_horizontal_inset = horizontal_inset * scale;
+
+ const float endcap_radius = endcap_width / 2;
+
+ // Construct the interior path by intersecting paths representing the left
+ // and right halves of the tab. Compared to computing the full path at once,
+ // this makes it easier to avoid overdraw in the top center near minimum
+ // width, and to implement cases where |horizontal_inset| != 0.
+ SkPath right_path;
+
+ right_path.moveTo(right, bottom);
+ // right_path.moveTo(right - 1 - scaled_horizontal_inset, bottom);
+
+ right_path.arcTo(endcap_radius, endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCW, right - endcap_radius, bottom - endcap_radius);
+ // right_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, -0.5 * scale,
+ // -2 * scale, -1.5 * scale);
+
+ right_path.lineTo(right - endcap_radius, endcap_radius);
+ // right_path.lineTo(
+ // right - 1 - scaled_horizontal_inset - (endcap_width - 2) * scale,
+ // 2.5 * scale);
+
+ right_path.arcTo(endcap_radius, endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCCW, right - endcap_width, 0);
+ // right_path.rCubicTo(-0.375 * scale, -1 * scale, -1.25 * scale, -1.5 * scale,
+ // -2 * scale, -1.5 * scale);
+
+ right_path.lineTo(0, 0);
+ right_path.lineTo(0, bottom);
+ right_path.close();
+
+ SkPath left_path;
+ // const float scaled_endcap_width = 1 + endcap_width * scale;
+ left_path.moveTo(endcap_width, 0);
+ // left_path.moveTo(scaled_endcap_width + scaled_horizontal_inset, scale);
+
+ left_path.arcTo(endcap_radius, endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCCW, endcap_radius, endcap_radius);
+ // left_path.rCubicTo(-0.75 * scale, 0, -1.625 * scale, 0.5 * scale, -2 * scale,
+ // 1.5 * scale);
+
+ left_path.lineTo(endcap_radius, bottom - endcap_radius);
+ // left_path.lineTo(1 + scaled_horizontal_inset + 2 * scale,
+ // bottom - 1.5 * scale);
+
+ left_path.arcTo(endcap_radius, endcap_radius, 90, SkPath::kSmall_ArcSize,
+ SkPathDirection::kCW, 0, bottom);
+ // left_path.rCubicTo(-0.375 * scale, scale, -1.25 * scale, 1.5 * scale,
+ // -2 * scale, 1.5 * scale);
+
+ left_path.lineTo(right, bottom);
+ left_path.lineTo(right, 0);
+ left_path.close();
+
+ SkPath complete_path;
+ Op(left_path, right_path, SkPathOp::kIntersect_SkPathOp, &complete_path);
+ return complete_path;
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(1);
+ SkPath path = GetInteriorPath(1.f, SkISize::Make(250, 36), 16);
+ canvas->drawPath(path, p);
+
+ // canvas->drawLine(20, 20, 100, 100, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/DCIToXYZD50.cpp b/docs/examples/DCIToXYZD50.cpp
new file mode 100644
index 0000000..c817454
--- /dev/null
+++ b/docs/examples/DCIToXYZD50.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(DCIToXYZD50, 512, 256, true, 0) {
+void draw(SkCanvas* canvas) {
+ SkColorSpacePrimaries p;
+ // DCI-P3 Primaries from https://en.wikipedia.org/wiki/DCI-P3
+ p.fRX = 0.680f; p.fRY = 0.320f;
+ p.fGX = 0.265f; p.fGY = 0.690f;
+ p.fBX = 0.150f; p.fBY = 0.060f;
+
+ // DCI-P3 D65
+ p.fWX = 0.3127f; p.fWY = 0.3290f;
+
+ // DCI-P3 Theater
+ // p.fWX = 0.314; p.fWY = 0.351;
+
+ skcms_Matrix3x3 toXYZ;
+ p.toXYZD50(&toXYZ);
+
+ for (int i = 0; i < 3; ++i) {
+ SkDebugf("%f %f %f\n", toXYZ.vals[i][0], toXYZ.vals[i][1], toXYZ.vals[i][2]);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/Octopus_Generator.cpp b/docs/examples/Octopus_Generator.cpp
new file mode 100644
index 0000000..3602c27
--- /dev/null
+++ b/docs/examples/Octopus_Generator.cpp
@@ -0,0 +1,30 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(Octopus_Generator, 256, 256, false, 0) {
+void paintOctopus(int x, int y, int size_base, SkColor color, SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(color);
+ int radius = 3 * size_base;
+ canvas->drawCircle(x, y, radius, paint);
+ for (int leg = 0; leg < 8; ++leg) {
+ canvas->drawCircle(x - radius + (2 * radius / 7.5 * leg),
+ y + radius - pow(abs(4 - leg), 2), size_base / 2 + 2, paint);
+ }
+ paint.setColor(SkColorSetRGB(SkTMin(255u, SkColorGetR(color) + 20),
+ SkTMin(255u, SkColorGetG(color) + 20),
+ SkTMin(255u, SkColorGetB(color) + 20)));
+ canvas->drawCircle(x - size_base, y + size_base, size_base / 2, paint);
+ canvas->drawCircle(x + size_base, y + size_base, size_base / 2, paint);
+}
+
+void draw(SkCanvas* canvas) {
+ SkRandom rand;
+
+ for (int i = 0; i < 400; ++i) {
+ paintOctopus(rand.nextRangeScalar(0, 256), rand.nextRangeScalar(0, 256),
+ rand.nextRangeScalar(6, 12), rand.nextU() | 0xFF0000000, canvas);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/PaintDump.cpp b/docs/examples/PaintDump.cpp
new file mode 100644
index 0000000..9090fde
--- /dev/null
+++ b/docs/examples/PaintDump.cpp
@@ -0,0 +1,108 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(PaintDump, 256, 256, true, 0) {
+static const char* str(SkPaint::Cap v) {
+ switch (v) {
+ case SkPaint::kButt_Cap: return "SkPaint::kButt_Cap";
+ case SkPaint::kRound_Cap: return "SkPaint::kRound_Cap";
+ case SkPaint::kSquare_Cap: return "SkPaint::kSquare_Cap";
+ default: return "?";
+ }
+}
+static const char* str(SkPaint::Join v) {
+ switch (v) {
+ case SkPaint::kMiter_Join: return "SkPaint::kMiter_Join";
+ case SkPaint::kRound_Join: return "SkPaint::kRound_Join";
+ case SkPaint::kBevel_Join: return "SkPaint::kBevel_Join";
+ default: return "?";
+ }
+}
+static const char* str(SkPaint::Style v) {
+ switch (v) {
+ case SkPaint::kFill_Style: return "SkPaint::kFill_Style";
+ case SkPaint::kStroke_Style: return "SkPaint::kStroke_Style";
+ case SkPaint::kStrokeAndFill_Style: return "SkPaint::kStrokeAndFill_Style";
+ default: return "?";
+ }
+}
+
+static const char* str(SkFilterQuality v) {
+ switch (v) {
+ case kNone_SkFilterQuality: return "kNone_SkFilterQuality";
+ case kLow_SkFilterQuality: return "kLow_SkFilterQuality";
+ case kMedium_SkFilterQuality: return "kMedium_SkFilterQuality";
+ case kHigh_SkFilterQuality: return "kHigh_SkFilterQuality";
+ default: return "?";
+ }
+}
+
+static const char* str(bool v) { return v ? "true" : "false"; }
+
+SkString PaintStringDump(const SkPaint& p) {
+ SkString s("SkPaint p;\n");
+ SkPaint d;
+ if (d.getStrokeWidth() != p.getStrokeWidth()) {
+ s.appendf("p.setStrokeWidth(%.9g);\n", p.getStrokeWidth());
+ }
+ if (d.getStrokeMiter() != p.getStrokeMiter()) {
+ s.appendf("p.setStrokeMiter(%.9g);\n", p.getStrokeMiter());
+ }
+ SkColor4f c = p.getColor4f();
+ if (c != d.getColor4f()) {
+ s.appendf("p.setColor4f({%.9g, %.9g, %.9g, %.9g}, nullptr);\n", c.fR, c.fG, c.fB, c.fA);
+ }
+ if (d.isAntiAlias() != p.isAntiAlias()) {
+ s.appendf("p.setAntiAlias(%s);\n", str(p.isAntiAlias()));
+ }
+ if (d.isDither() != p.isDither()) {
+ s.appendf("p.setDither(%s);\n", str(p.isDither()));
+ }
+ if (d.getStrokeCap() != p.getStrokeCap()) {
+ s.appendf("p.setStrokeCap(%s);\n", str(p.getStrokeCap()));
+ }
+ if (d.getStrokeJoin() != p.getStrokeJoin()) {
+ s.appendf("p.setStrokeJoin(%s);\n", str(p.getStrokeJoin()));
+ }
+ if (d.getStyle() != p.getStyle()) {
+ s.appendf("p.setStyle(%s);\n", str(p.getStyle()));
+ }
+ if (d.getFilterQuality() != p.getFilterQuality()) {
+ s.appendf("p.setFilterQuality(%s);\n", str(p.getFilterQuality()));
+ }
+ if (d.getBlendMode() != p.getBlendMode()) {
+ s.appendf("p.setBlendMode(SkBlendMode::k%s);\n", SkBlendMode_Name(p.getBlendMode()));
+ }
+ if (p.getPathEffect()) {
+ s.appendf("p.setPathEffect(/*FIXME*/);\n");
+ }
+ if (p.getShader()) {
+ s.appendf("p.setShader(/*FIXME*/);\n");
+ }
+ if (p.getMaskFilter()) {
+ s.appendf("p.setMaskFilter(/*FIXME*/);\n");
+ }
+ if (p.getColorFilter()) {
+ s.appendf("p.setColorFilter(/*FIXME*/);\n");
+ }
+ if (p.getImageFilter()) {
+ s.appendf("p.setImageFilter(/*FIXME*/);\n");
+ }
+ return s;
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(10);
+ p.setBlendMode(SkBlendMode::kDstOver);
+ p.setStrokeCap(SkPaint::kRound_Cap);
+ p.setShader(image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
+
+ auto s = PaintStringDump(p);
+ SkDebugf("%s", s.c_str());
+}
+
+} // END FIDDLE
diff --git a/docs/examples/SKIA_LOGO.cpp b/docs/examples/SKIA_LOGO.cpp
new file mode 100644
index 0000000..f667946
--- /dev/null
+++ b/docs/examples/SKIA_LOGO.cpp
@@ -0,0 +1,100 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SKIA_LOGO, 816, 464, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->scale(4.0f, 4.0f);
+ const SkColor background = SK_ColorWHITE; // SK_ColorTRANSPARENT;
+ const SkColor rgb[] = {0xFFE94037, 0xFF70BF4F, 0xFF465BA6};
+ const SkColor lettering = 0xFF292929;
+ const SkColor lineColors[2] = {0x30565656, 0xFF565656};
+ SkPath s, k, a, triangle;
+ SkPaint p;
+ p.setAntiAlias(true);
+
+ canvas->clear(background);
+ canvas->scale(0.363f, 0.363f);
+
+ p.setColor(rgb[1]);
+ canvas->drawRect({326.0, 82.25, 343.9, 249.2}, p);
+ p.setColor(rgb[0]);
+ canvas->drawRect({310.2, 82.25, 327.0, 249.2}, p);
+ p.setColor(rgb[2]);
+ canvas->drawRect({342.9, 82.25, 358.87, 249.2}, p);
+
+ p.setColor(lettering);
+ canvas->drawCircle(335.355, 45.965, 29.25, p);
+
+ s.moveTo(34.63, 100.63);
+ s.cubicTo(44.38, 88.57, 59.87, 82.86, 74.88, 81.2);
+ s.cubicTo(97.4, 78.5, 120.27, 83.25, 140.87, 92.37);
+ s.lineTo(127.12, 127.14);
+ s.cubicTo(113.55, 121.16, 99.04, 115.9, 83.98, 116.56);
+ s.cubicTo(78.86, 116.75, 72.88, 118.54, 70.71, 123.69);
+ s.cubicTo(68.62, 128.43, 71.52, 133.68, 75.58, 136.27);
+ s.cubicTo(91.49, 146.66, 110.67, 151.38, 125.46, 163.6);
+ s.cubicTo(132.35, 169.11, 137.33, 176.9, 139.36, 185.49);
+ s.cubicTo(142.55, 199.14, 140.94, 214.31, 133.13, 226.17);
+ s.cubicTo(126.23, 236.96, 114.82, 244.16, 102.75, 247.89);
+ s.cubicTo(87.95, 252.51, 72.16, 252.21, 56.88, 250.78);
+ s.cubicTo(45.54, 249.72, 34.64, 246.05, 24.32, 241.36);
+ s.lineTo(24.25, 201.1);
+ s.cubicTo(38.23, 208.15, 53.37, 213.15, 68.98, 214.75);
+ s.cubicTo(75.42, 215.25, 82.17, 215.63, 88.31, 213.27);
+ s.cubicTo(92.84, 211.53, 96.4, 206.93, 95.86, 201.93);
+ s.cubicTo(95.64, 196.77, 91.1, 193.38, 87.03, 190.99);
+ s.cubicTo(71.96, 182.67, 54.94, 177.66, 41.5, 166.57);
+ s.cubicTo(33.19, 159.73, 27.51, 149.8, 26.1, 139.11);
+ s.cubicTo(24.09, 125.88, 25.91, 111.25, 34.63, 100.63);
+ canvas->drawPath(s, p);
+
+ k.moveTo(160.82, 82.85);
+ k.lineTo(206.05, 82.85);
+ k.lineTo(206.05, 155.15);
+ k.lineTo(254.83, 82.84);
+ k.lineTo(304.01, 82.85);
+ k.lineTo(251.52, 157.27);
+ k.lineTo(303.09, 249.42);
+ k.lineTo(252.28, 249.4);
+ k.lineTo(219.18, 185.75);
+ k.lineTo(206.23, 193.45);
+ k.lineTo(206.05, 249.42);
+ k.lineTo(160.82, 249.42);
+ k.lineTo(160.82, 82.85);
+ canvas->drawPath(k, p);
+
+ a.moveTo(426.45, 218.16);
+ a.lineTo(480.705, 218.16);
+ a.lineTo(489.31, 249.4);
+ a.lineTo(538.54, 249.42);
+ a.lineTo(483.56, 82.18);
+ a.lineTo(423.43, 82.17);
+ a.lineTo(369.13, 249.42);
+ a.lineTo(418.5, 249.47);
+ a.lineTo(453.75, 109.83);
+ a.lineTo(471.77, 181.28);
+ a.lineTo(430.5, 181.28);
+ canvas->drawPath(a, p);
+
+ triangle.reset();
+ triangle.moveTo(362.64, 257.32);
+ triangle.lineTo(335.292, 293.392);
+ triangle.lineTo(307.8, 257.48);
+ triangle.lineTo(362.64, 257.32);
+ p.setColor(lettering);
+ canvas->drawPath(triangle, p);
+
+ // line
+ const SkPoint pts[2] = {{160, 290}, {341, 290}};
+ p.setShader(SkGradientShader::MakeLinear(pts, lineColors, NULL, 2, SkTileMode::kClamp));
+ if (true) {
+ SkRRect rrect;
+ rrect.setRectXY({138, 291, 341, 300}, 25.0, 5.0);
+ canvas->drawRRect(rrect, p);
+ } else {
+ SkPath path;
+ path.addRoundRect({138, 291, 341, 299.95}, 25.0, 5.0);
+ canvas->drawPath(path, p);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/SKIA_LOGO_svg.cpp b/docs/examples/SKIA_LOGO_svg.cpp
new file mode 100644
index 0000000..fe3cb5b
--- /dev/null
+++ b/docs/examples/SKIA_LOGO_svg.cpp
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SKIA_LOGO_svg, 816, 464, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->scale(4.0f, 4.0f);
+ const SkColor background = SK_ColorWHITE; // SK_ColorTRANSPARENT;
+ const SkColor rgb[] = {0xFFE94037, 0xFF70BF4F, 0xFF465BA6};
+ const SkColor lettering = 0xFF292929;
+ const SkColor lineColors[2] = {0x30565656, 0xFF565656};
+ SkPath s, k, a, triangle;
+ SkPaint p;
+ p.setAntiAlias(true);
+
+ canvas->clear(background);
+ canvas->scale(0.363f, 0.363f);
+
+ p.setColor(rgb[1]);
+ canvas->drawRect({326.0, 82.25, 343.9, 249.2}, p);
+ p.setColor(rgb[0]);
+ canvas->drawRect({310.2, 82.25, 327.0, 249.2}, p);
+ p.setColor(rgb[2]);
+ canvas->drawRect({342.9, 82.25, 358.87, 249.2}, p);
+
+ p.setColor(lettering);
+ canvas->drawCircle(335.355, 45.965, 29.25, p);
+
+ SkParsePath::FromSVGString("M34.63 100.63C44.38 88.57 59.87 82.86 74.88 81.2"
+ "C97.4 78.5 120.27 83.25 140.87 92.37L127.12 127.14C113.55 121.16 99.04 115.9 83.98 116.56"
+ "C78.86 116.75 72.88 118.54 70.71 123.69C68.62 128.43 71.52 133.68 75.58 136.27"
+ "C91.49 146.66 110.67 151.38 125.46 163.6C132.35 169.11 137.33 176.9 139.36 185.49"
+ "C142.55 199.14 140.94 214.31 133.13 226.17C126.23 236.96 114.82 244.16 102.75 247.89"
+ "C87.95 252.51 72.16 252.21 56.88 250.78C45.54 249.72 34.64 246.05 24.32 241.36"
+ "L24.25 201.1C38.23 208.15 53.37 213.15 68.98 214.75C75.42 215.25 82.17 215.63 88.31 213.27"
+ "C92.84 211.53 96.4 206.93 95.86 201.93C95.64 196.77 91.1 193.38 87.03 190.99"
+ "C71.96 182.67 54.94 177.66 41.5 166.57C33.19 159.73 27.51 149.8 26.1 139.11"
+ "C24.09 125.88 25.91 111.25 34.63 100.63", &s);
+ canvas->drawPath(s, p);
+
+ SkParsePath::FromSVGString("M160.82 82.85L206.05 82.85L206.05 155.15L254.83 82.84"
+ "L304.01 82.85L251.52 157.27L303.09 249.42L252.28 249.4L219.18 185.75L206.23 193.45"
+ "L206.05 249.42L160.82 249.42L160.82 82.85", &k);
+ canvas->drawPath(k, p);
+
+ SkParsePath::FromSVGString("M426.45 218.16L480.705 218.16L489.31 249.4L538.54 249.42"
+ "L483.56 82.18L423.43 82.17L369.13 249.42L418.5 249.47L453.75 109.83L471.77 181.28"
+ "L430.5 181.28", &a);
+ canvas->drawPath(a, p);
+
+ SkParsePath::FromSVGString("M362.64 257.32L335.292 293.392L307.8 257.48L362.64 257.32",
+ &triangle);
+ canvas->drawPath(triangle, p);
+
+ const SkPoint pts[2] = {{160, 290}, {341, 290}};
+ p.setShader(SkGradientShader::MakeLinear(
+ pts, lineColors, NULL, 2, SkTileMode::kClamp));
+ SkRRect rrect;
+ rrect.setRectXY({138, 291, 341, 300}, 25.0, 5.0);
+ canvas->drawRRect(rrect, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/SkFontMgr_example.cpp b/docs/examples/SkFontMgr_example.cpp
new file mode 100644
index 0000000..d588a3f
--- /dev/null
+++ b/docs/examples/SkFontMgr_example.cpp
@@ -0,0 +1,35 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkFontMgr_example, 1280, 512, true, 0) {
+const char* tostr(SkFontStyle::Slant s) {
+ switch (s) {
+ case SkFontStyle::kUpright_Slant: return "SkFontStyle::kUpright_Slant";
+ case SkFontStyle::kItalic_Slant: return "SkFontStyle::kItalic_Slant";
+ case SkFontStyle::kOblique_Slant: return "SkFontStyle::kOblique_Slant";
+ default: return "";
+ }
+}
+
+void draw(SkCanvas* canvas) {
+ SkDebugf("sk_sp<SkFontMgr> mgr(SkFontMgr::RefDefault());\n\n");
+
+ sk_sp<SkFontMgr> mgr(SkFontMgr::RefDefault());
+ for (int i = 0; i < mgr->countFamilies(); ++i) {
+ SkString familyName;
+ mgr->getFamilyName(i, &familyName);
+ sk_sp<SkFontStyleSet> styleSet(mgr->createStyleSet(i));
+ int N = styleSet->count();
+ for (int j = 0; j < N; ++j) {
+ SkFontStyle fontStyle;
+ SkString style;
+ styleSet->getStyle(j, &fontStyle, &style);
+ SkDebugf("SkFont font(mgr->legacyMakeTypeface(\"%s\",\n"
+ " SkFontStyle(%3d, %1d, %-27s));\n",
+ familyName.c_str(), fontStyle.weight(), fontStyle.width(),
+ tostr(fontStyle.slant()));
+ }
+ SkDebugf("\n");
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/SkFontMgr_example2.cpp b/docs/examples/SkFontMgr_example2.cpp
new file mode 100644
index 0000000..5e0131d
--- /dev/null
+++ b/docs/examples/SkFontMgr_example2.cpp
@@ -0,0 +1,38 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkFontMgr_example2, 1536, 512, false, 0) {
+const char* tostr(SkFontStyle::Slant s) {
+ switch (s) {
+ case SkFontStyle::kUpright_Slant: return "SkFontStyle::kUpright_Slant";
+ case SkFontStyle::kItalic_Slant: return "SkFontStyle::kItalic_Slant";
+ case SkFontStyle::kOblique_Slant: return "SkFontStyle::kOblique_Slant";
+ default: return "";
+ }
+}
+
+void draw(SkCanvas* canvas) {
+ float x = 10, y = 10;
+ float textScale = 24;
+
+ sk_sp<SkFontMgr> mgr(SkFontMgr::RefDefault());
+ for (int i = 0; i < mgr->countFamilies(); ++i) {
+ SkString familyName;
+ mgr->getFamilyName(i, &familyName);
+ sk_sp<SkFontStyleSet> styleSet(mgr->createStyleSet(i));
+ for (int j = 0; j < styleSet->count(); ++j) {
+ SkFontStyle fontStyle;
+ SkString style;
+ styleSet->getStyle(j, &fontStyle, &style);
+ auto s = SkStringPrintf(
+ "SkFont font(mgr->legacyMakeTypeface(\"%s\", SkFontStyle(%3d, %1d, %-27s), "
+ "%g);",
+ familyName.c_str(), fontStyle.weight(), fontStyle.width(),
+ tostr(fontStyle.slant()), textScale);
+ SkFont font(mgr->legacyMakeTypeface(familyName.c_str(), fontStyle), textScale);
+ y += font.getSpacing() * 1.5;
+ canvas->drawString(s, x, y, font, SkPaint());
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/SkImage_to_PPM_ascii.cpp b/docs/examples/SkImage_to_PPM_ascii.cpp
new file mode 100644
index 0000000..13e5c7f
--- /dev/null
+++ b/docs/examples/SkImage_to_PPM_ascii.cpp
@@ -0,0 +1,54 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkImage_to_PPM_ascii, 256, 256, true, 4) {
+void dump_txt(const SkData* data, const char* name) {
+ if (data) {
+ SkDebugf("\ncat > %s << EOF\n", name);
+ size_t s = data->size();
+ const char* d = (const char*)data->bytes();
+ while (s > 0) {
+ int l = (int)SkTMin(s, (size_t)1024);
+ SkDebugf("%.*s", l, d);
+ s -= l;
+ d += l;
+ }
+ SkDebugf("\nEOF\n\n");
+ }
+}
+
+sk_sp<SkData> Encode_PPM_A(const SkPixmap& src) {
+ if (src.width() <= 0 || src.height() <= 0 || !src.addr() ||
+ src.colorType() == kUnknown_SkColorType) {
+ return nullptr;
+ }
+ SkDynamicMemoryWStream buf;
+ SkString s = SkStringPrintf("P3\n%d %d\n255\n", src.width(), src.height());
+ buf.write(s.c_str(), s.size());
+ for (int y = 0; y < src.height(); ++y) {
+ for (int x = 0; x < src.height(); ++x) {
+ char buffer[13];
+ SkColor c = src.getColor(x, y);
+ int n = snprintf(buffer, sizeof(buffer), "%d %d %d\n", SkColorGetR(c),
+ SkColorGetG(c), SkColorGetB(c));
+ if (n < 6 || n + 1 > (int)sizeof(buffer)) {
+ return nullptr;
+ }
+ buf.write(buffer, n);
+ }
+ }
+ return buf.detachAsData();
+}
+
+SkBitmap ToBitmap(SkImage * img) {
+ SkBitmap bitmap;
+ (void)img->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode);
+ return bitmap;
+}
+
+void draw(SkCanvas*) {
+ SkBitmap bitmap = ToBitmap(image.get());
+ sk_sp<SkData> data = Encode_PPM_A(bitmap.pixmap());
+ dump_txt(data.get(), "fooa.ppm");
+}
+} // END FIDDLE
diff --git a/docs/examples/SkImage_to_PPM_binary.cpp b/docs/examples/SkImage_to_PPM_binary.cpp
new file mode 100644
index 0000000..6752ee3
--- /dev/null
+++ b/docs/examples/SkImage_to_PPM_binary.cpp
@@ -0,0 +1,52 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkImage_to_PPM_binary, 256, 256, true, 4) {
+void print_data(const SkData* data, const char* name) {
+ if (data) {
+ SkDebugf("\nxxd -r -p > %s << EOF", name);
+ size_t s = data->size();
+ const uint8_t* d = data->bytes();
+ for (size_t i = 0; i < s; ++i) {
+ if (i % 40 == 0) {
+ SkDebugf("\n");
+ }
+ SkDebugf("%02x", d[i]);
+ }
+ SkDebugf("\nEOF\n\n");
+ }
+}
+
+sk_sp<SkData> Encode_PPM_B(const SkPixmap& src) {
+ if (src.width() <= 0 || src.height() <= 0 || !src.addr() ||
+ src.colorType() == kUnknown_SkColorType) {
+ return nullptr;
+ }
+ SkString s = SkStringPrintf("P6\n%d %d\n255\n", src.width(), src.height());
+ auto result = SkData::MakeUninitialized(s.size() + 3 * src.width() * src.height());
+ uint8_t* ptr = static_cast<uint8_t*>(result->writable_data());
+ memcpy(ptr, s.c_str(), s.size());
+ ptr += s.size();
+ for (int y = 0; y < src.height(); ++y) {
+ for (int x = 0; x < src.height(); ++x) {
+ SkColor c = src.getColor(x, y);
+ *ptr++ = SkColorGetR(c);
+ *ptr++ = SkColorGetG(c);
+ *ptr++ = SkColorGetB(c);
+ }
+ }
+ return result;
+}
+
+SkBitmap ToBitmap(SkImage * img) {
+ SkBitmap bitmap;
+ (void)img->asLegacyBitmap(&bitmap, SkImage::kRO_LegacyBitmapMode);
+ return bitmap;
+}
+
+void draw(SkCanvas*) {
+ SkBitmap bitmap = ToBitmap(image.get());
+ sk_sp<SkData> data = Encode_PPM_B(bitmap.pixmap());
+ print_data(data.get(), "foo.ppm");
+}
+} // END FIDDLE
diff --git a/docs/examples/SkParsePath_FromSVGString.cpp b/docs/examples/SkParsePath_FromSVGString.cpp
new file mode 100644
index 0000000..9a0da7f
--- /dev/null
+++ b/docs/examples/SkParsePath_FromSVGString.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkParsePath_FromSVGString, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ const char pathString[] =
+ "M 243 128 "
+ "L 24 178 "
+ "L 200 38 "
+ "L 102 240 "
+ "L 102 16 "
+ "L 200 218 "
+ "L 24 78 "
+ "Z";
+ SkPath path;
+ SkParsePath::FromSVGString(pathString, &path);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeCap(SkPaint::kRound_Cap);
+ paint.setStrokeWidth(2);
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/SkParsePath_ToSVGString.cpp b/docs/examples/SkParsePath_ToSVGString.cpp
new file mode 100644
index 0000000..91e2da8
--- /dev/null
+++ b/docs/examples/SkParsePath_ToSVGString.cpp
@@ -0,0 +1,21 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkParsePath_ToSVGString, 256, 256, true, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(sk_float_round(C + R), sk_float_round(C));
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(sk_float_round(C + R * cos(a)), sk_float_round(C + R * sin(a)));
+ }
+ return path;
+}
+
+void draw(SkCanvas* canvas) {
+ SkString s;
+ SkParsePath::ToSVGString(star(), &s);
+ SkDebugf("%s\n", s.c_str());
+}
+} // END FIDDLE
diff --git a/docs/examples/SkPath_arcTo_example.cpp b/docs/examples/SkPath_arcTo_example.cpp
new file mode 100644
index 0000000..3c8cbf1
--- /dev/null
+++ b/docs/examples/SkPath_arcTo_example.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkPath_arcTo_example, 512, 512, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.5);
+
+ SkRect oval = {64, 64, 448, 448};
+ canvas->drawOval(oval, paint);
+ float startAngle = 0;
+ float sweepAngle = 60;
+
+ SkPath arc;
+ arc.arcTo(oval, startAngle, sweepAngle, false);
+
+ paint.setStrokeWidth(5);
+ paint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ canvas->drawPath(arc, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/SkPath_arcto_conic_parametric.cpp b/docs/examples/SkPath_arcto_conic_parametric.cpp
new file mode 100644
index 0000000..1c3f91d
--- /dev/null
+++ b/docs/examples/SkPath_arcto_conic_parametric.cpp
@@ -0,0 +1,72 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkPath_arcto_conic_parametric, 512, 512, false, 0) {
+SkPoint conic(SkPoint p0, SkPoint p1, SkPoint p2, float w, float t) {
+ float s = 1 - t;
+ return {((s * s * p0.x()) + (2 * s * t * w * p1.x()) + (t * t * p2.x())) /
+ ((s * s) + (w * 2 * s * t) + (t * t)),
+ ((s * s * p0.y()) + (2 * s * t * w * p1.y()) + (t * t * p2.y())) /
+ ((s * s) + (w * 2 * s * t) + (t * t))};
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.5);
+
+ SkPoint center = {256, 256};
+ float r = 192;
+ SkRect oval = {center.x() - r, center.y() - r, center.x() + r, center.y() + r};
+ canvas->drawOval(oval, paint);
+ float startAngle = 0;
+ float sweepAngle = 179;
+
+ SkPath arc;
+ arc.arcTo(oval, startAngle, sweepAngle, false);
+
+ paint.setStrokeWidth(5);
+ paint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ canvas->drawPath(arc, paint);
+
+ SkPaint pointPaint;
+ pointPaint.setAntiAlias(true);
+ pointPaint.setStrokeWidth(8);
+ pointPaint.setStrokeCap(SkPaint::kRound_Cap);
+ pointPaint.setColor(SkColorSetARGB(255, 0, 255, 0));
+
+ float finalAngle = startAngle + sweepAngle;
+ float middleAngle = startAngle + 0.5f * sweepAngle;
+ float weight = cos(SkDegreesToRadians(sweepAngle) / 2);
+ SkPoint p0 = {r * SkScalarCos(SkDegreesToRadians(startAngle)),
+ r * SkScalarSin(SkDegreesToRadians(startAngle))};
+ float d = r / weight;
+ SkPoint p1 = {d * SkScalarCos(SkDegreesToRadians(middleAngle)),
+ d * SkScalarSin(SkDegreesToRadians(middleAngle))};
+ SkPoint p2 = {r * SkScalarCos(SkDegreesToRadians(finalAngle)),
+ r * SkScalarSin(SkDegreesToRadians(finalAngle))};
+ p0 += center;
+ p1 += center;
+ p2 += center;
+
+ const int N = 8;
+ for (int i = 0; i <= N; ++i) {
+ SkPoint p = conic(p0, p1, p2, weight, (float)i / N);
+ canvas->drawPoint(p.x(), p.y(), pointPaint);
+ }
+ pointPaint.setColor(SkColorSetARGB(255, 255, 0, 0));
+ canvas->drawPoint(p0.x(), p0.y(), pointPaint);
+ canvas->drawPoint(p1.x(), p1.y(), pointPaint);
+ canvas->drawPoint(p2.x(), p2.y(), pointPaint);
+
+ SkPath weightedQuadratic;
+ weightedQuadratic.moveTo(p0);
+ weightedQuadratic.conicTo(p1, p2, weight);
+ paint.setColor(SK_ColorCYAN);
+ paint.setStrokeWidth(1);
+ canvas->drawPath(weightedQuadratic, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/SkPath_arcto_conic_parametric2.cpp b/docs/examples/SkPath_arcto_conic_parametric2.cpp
new file mode 100644
index 0000000..95b8442
--- /dev/null
+++ b/docs/examples/SkPath_arcto_conic_parametric2.cpp
@@ -0,0 +1,93 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkPath_arcto_conic_parametric2, 512, 512, false, 0) {
+/** Add a weighted quadratic bezier from the last point, approaching control point
+ (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
+ this contour, the first point is automatically set to (0,0).
+ If the starting point is (x0, y0), then this curve is defined as the
+ paramentric curve as `t` goes from 0 to 1:
+ s := 1 - t
+ x := ((s * s * x0) + (w * 2 * s * t * x1) + (t * t * x2)) /
+ ((s * s) + (w * 2 * s * t) + (t * t))
+ y := ((s * s * y0) + (w * 2 * s * t * y1) + (t * t * y2)) /
+ ((s * s) + (w * 2 * s * t) + (t * t))
+ @param x1 The x-coordinate of the control point on a quadratic curve
+ @param y1 The y-coordinate of the control point on a quadratic curve
+ @param x2 The x-coordinate of the end point on a quadratic curve
+ @param y2 The y-coordinate of the end point on a quadratic curve
+ @param w The weight of the control point (x1,y1)
+*/
+
+SkPoint conic(SkPoint p0, SkPoint p1, SkPoint p2, float w, float t) {
+ float s = 1 - t;
+ return {((s * s * p0.x()) + (2 * s * t * w * p1.x()) + (t * t * p2.x())) /
+ ((s * s) + (w * 2 * s * t) + (t * t)),
+ ((s * s * p0.y()) + (2 * s * t * w * p1.y()) + (t * t * p2.y())) /
+ ((s * s) + (w * 2 * s * t) + (t * t))};
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(1);
+
+ SkPoint center = {256, 256};
+ float r = 192;
+ SkRect oval = {center.x() - r, center.y() - r, center.x() + r, center.y() + r};
+ canvas->drawOval(oval, paint);
+ float startAngle = 15;
+ float sweepAngle = 75;
+
+ SkPath arc;
+ arc.arcTo(oval, startAngle, sweepAngle, false);
+
+ SkPaint arcPaint(paint);
+ arcPaint.setStrokeWidth(5);
+ arcPaint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ canvas->drawPath(arc, arcPaint);
+
+ SkPaint pointPaint;
+ pointPaint.setAntiAlias(true);
+ pointPaint.setStrokeWidth(8);
+ pointPaint.setStrokeCap(SkPaint::kRound_Cap);
+ pointPaint.setColor(SkColorSetARGB(255, 0, 255, 0));
+
+ float finalAngle = startAngle + sweepAngle;
+ float middleAngle = startAngle + 0.5f * sweepAngle;
+ float weight = cos(SkDegreesToRadians(sweepAngle) / 2);
+ SkPoint p0 = {r * SkScalarCos(SkDegreesToRadians(startAngle)),
+ r * SkScalarSin(SkDegreesToRadians(startAngle))};
+ float d = r / weight;
+ SkPoint p1 = {d * SkScalarCos(SkDegreesToRadians(middleAngle)),
+ d * SkScalarSin(SkDegreesToRadians(middleAngle))};
+ SkPoint p2 = {r * SkScalarCos(SkDegreesToRadians(finalAngle)),
+ r * SkScalarSin(SkDegreesToRadians(finalAngle))};
+ p0 += center;
+ p1 += center;
+ p2 += center;
+
+ canvas->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint);
+ canvas->drawLine(p1.x(), p1.y(), p2.x(), p2.y(), paint);
+
+ const int N = 16;
+ for (int i = 0; i <= N; ++i) {
+ SkPoint p = conic(p0, p1, p2, weight, (float)i / N);
+ canvas->drawPoint(p.x(), p.y(), pointPaint);
+ }
+ pointPaint.setColor(SkColorSetARGB(255, 255, 0, 0));
+ canvas->drawPoint(p0.x(), p0.y(), pointPaint);
+ canvas->drawPoint(p1.x(), p1.y(), pointPaint);
+ canvas->drawPoint(p2.x(), p2.y(), pointPaint);
+
+ SkPath weightedQuadratic;
+ weightedQuadratic.moveTo(p0);
+ weightedQuadratic.conicTo(p1, p2, weight);
+ paint.setColor(SK_ColorYELLOW);
+ paint.setStrokeWidth(2.5);
+ canvas->drawPath(weightedQuadratic, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/SkPath_cubicTo_example.cpp b/docs/examples/SkPath_cubicTo_example.cpp
new file mode 100644
index 0000000..2957527
--- /dev/null
+++ b/docs/examples/SkPath_cubicTo_example.cpp
@@ -0,0 +1,55 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkPath_cubicTo_example, 512, 512, false, 0) {
+/*
+ If the starting point is (x0, y0), then this curve is defined as the
+ paramentric curve as `t` goes from 0 to 1:
+ s := 1 - t
+ x := (s * s * s * x0) +
+ (3 * s * s * t * x1) +
+ (3 * s * t * t * x2) +
+ (t * t * t * x3)
+ y := (s * s * s * y0) +
+ (3 * s * s * t * y1) +
+ (3 * s * t * t * y2) +
+ (t * t * t * y3)
+
+*/
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+ SkFont font(nullptr, 32);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(5);
+
+ SkPoint a{128, 64};
+ SkPoint b{448, 448};
+ SkPoint c{64, 448};
+ SkPoint d{384, 64};
+
+ SkPath threeSegments;
+ threeSegments.moveTo(a);
+ threeSegments.lineTo(b);
+ threeSegments.lineTo(c);
+ threeSegments.lineTo(d);
+
+ canvas->drawPath(threeSegments, paint);
+
+ paint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ SkPath cubicCurve;
+ cubicCurve.moveTo(a);
+ cubicCurve.cubicTo(b, c, d);
+ canvas->drawPath(cubicCurve, paint);
+
+ SkPaint textPaint;
+ textPaint.setColor(SkColorSetARGB(255, 0, 255, 0));
+ textPaint.setAntiAlias(true);
+ canvas->drawString("a", a.x(), a.y(), font, textPaint);
+ canvas->drawString("b", b.x(), b.y(), font, textPaint);
+ canvas->drawString("c", c.x() - 20, c.y(), font, textPaint);
+ canvas->drawString("d", d.x(), d.y(), font, textPaint);
+}
+} // END FIDDLE
diff --git a/docs/examples/SkPath_cubicTo_example_parametric.cpp b/docs/examples/SkPath_cubicTo_example_parametric.cpp
new file mode 100644
index 0000000..3d9fdd0
--- /dev/null
+++ b/docs/examples/SkPath_cubicTo_example_parametric.cpp
@@ -0,0 +1,76 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkPath_cubicTo_example_parametric, 512, 512, false, 0) {
+/*
+ If the starting point is (x0, y0), then this curve is defined as the
+ paramentric curve as `t` goes from 0 to 1:
+ s := 1 - t
+ x := (s * s * s * x0) +
+ (3 * s * s * t * x1) +
+ (3 * s * t * t * x2) +
+ (t * t * t * x3)
+ y := (s * s * s * y0) +
+ (3 * s * s * t * y1) +
+ (3 * s * t * t * y2) +
+ (t * t * t * y3)
+
+*/
+
+SkPoint cubic(SkPoint p0, SkPoint p1, SkPoint p2, SkPoint p3, float t) {
+ float s = 1 - t;
+ return {(s * s * s * p0.x()) + (3 * s * s * t * p1.x()) + (3 * s * t * t * p2.x()) +
+ (t * t * t * p3.x()),
+ (s * s * s * p0.y()) + (3 * s * s * t * p1.y()) + (3 * s * t * t * p2.y()) +
+ (t * t * t * p3.y())};
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+ SkFont font(nullptr, 32);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(5);
+
+ SkPoint a{136, 64};
+ SkPoint b{448, 448};
+ SkPoint c{64, 448};
+ SkPoint d{376, 64};
+
+ SkPath threeSegments;
+ threeSegments.moveTo(a);
+ threeSegments.lineTo(b);
+ threeSegments.lineTo(c);
+ threeSegments.lineTo(d);
+
+ canvas->drawPath(threeSegments, paint);
+
+ paint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ SkPath cubicCurve;
+ cubicCurve.moveTo(a);
+ cubicCurve.cubicTo(b, c, d);
+ canvas->drawPath(cubicCurve, paint);
+
+ SkPaint textPaint;
+ textPaint.setColor(SkColorSetARGB(255, 0, 255, 0));
+ textPaint.setAntiAlias(true);
+ canvas->drawString("a", a.x(), a.y(), font, textPaint);
+ canvas->drawString("b", b.x(), b.y(), font, textPaint);
+ canvas->drawString("c", c.x() - 20, c.y(), font, textPaint);
+ canvas->drawString("d", d.x(), d.y(), font, textPaint);
+
+ SkPaint pointPaint;
+ pointPaint.setAntiAlias(true);
+ pointPaint.setStrokeWidth(8);
+ pointPaint.setStrokeCap(SkPaint::kRound_Cap);
+ pointPaint.setColor(SkColorSetARGB(255, 0, 255, 0));
+ const int N = 16;
+ for (int i = 0; i <= N; ++i) {
+ SkPoint p = cubic(a, b, c, d, (float)i / N);
+ canvas->drawPoint(p.x(), p.y(), pointPaint);
+ }
+ pointPaint.setColor(SkColorSetARGB(255, 255, 0, 0));
+}
+} // END FIDDLE
diff --git a/docs/examples/SkPath_quadTo_example.cpp b/docs/examples/SkPath_quadTo_example.cpp
new file mode 100644
index 0000000..0470d05
--- /dev/null
+++ b/docs/examples/SkPath_quadTo_example.cpp
@@ -0,0 +1,37 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkPath_quadTo_example, 512, 512, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(5);
+
+ SkPoint a{100, 100};
+ SkPoint b{200, 400};
+ SkPoint c{300, 100};
+
+ SkPath twoSegments;
+ twoSegments.moveTo(a);
+ twoSegments.lineTo(b);
+ twoSegments.lineTo(c);
+
+ canvas->drawPath(twoSegments, paint);
+
+ paint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ SkPath quadraticCurve;
+ quadraticCurve.moveTo(a);
+ quadraticCurve.quadTo(b, c);
+ canvas->drawPath(quadraticCurve, paint);
+
+ SkFont font(nullptr, 32);
+ SkPaint textPaint;
+ textPaint.setAntiAlias(true);
+ canvas->drawString("a", a.x(), a.y(), font, textPaint);
+ canvas->drawString("b", b.x() + 20, b.y() + 20, font, textPaint);
+ canvas->drawString("c", c.x(), c.y(), font, textPaint);
+}
+} // END FIDDLE
diff --git a/docs/examples/SkPath_quadTo_example_parametric.cpp b/docs/examples/SkPath_quadTo_example_parametric.cpp
new file mode 100644
index 0000000..c730577
--- /dev/null
+++ b/docs/examples/SkPath_quadTo_example_parametric.cpp
@@ -0,0 +1,65 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SkPath_quadTo_example_parametric, 512, 512, false, 0) {
+SkPoint quad(SkPoint p0, SkPoint p1, SkPoint p2, float t) {
+ float s = 1 - t;
+ return {(s * s * p0.x()) + (2 * s * t * p1.x()) + (t * t * p2.x()),
+ (s * s * p0.y()) + (2 * s * t * p1.y()) + (t * t * p2.y())};
+}
+
+/*
+
+ If the starting point is (x0, y0), then this curve is defined as the
+ paramentric curve as `t` goes from 0 to 1:
+
+ s := 1 - t
+ x := (s * s * x0) + (2 * s * t * x1) + (t * t * x2)
+ y := (s * s * y0) + (2 * s * t * y1) + (t * t * y2)
+
+*/
+
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(5);
+
+ SkPoint a{100, 100};
+ SkPoint b{200, 400};
+ SkPoint c{300, 100};
+
+ SkPath twoSegments;
+ twoSegments.moveTo(a);
+ twoSegments.lineTo(b);
+ twoSegments.lineTo(c);
+
+ canvas->drawPath(twoSegments, paint);
+
+ paint.setColor(SkColorSetARGB(255, 0, 0, 255));
+ SkPath quadraticCurve;
+ quadraticCurve.moveTo(a);
+ quadraticCurve.quadTo(b, c);
+ canvas->drawPath(quadraticCurve, paint);
+
+ SkFont font(nullptr, 32);
+ SkPaint textPaint;
+ textPaint.setAntiAlias(true);
+ canvas->drawString("a", a.x(), a.y(), font, textPaint);
+ canvas->drawString("b", b.x() + 20, b.y() + 20, font, textPaint);
+ canvas->drawString("c", c.x(), c.y(), font, textPaint);
+
+ SkPaint pointPaint;
+ pointPaint.setAntiAlias(true);
+ pointPaint.setStrokeWidth(8);
+ pointPaint.setStrokeCap(SkPaint::kRound_Cap);
+ pointPaint.setColor(SkColorSetARGB(255, 0, 255, 0));
+ int N = 15;
+ for (int i = 0; i <= N; ++i) {
+ SkPoint p = quad(a, b, c, (float)i / N);
+ canvas->drawPoint(p.x(), p.y(), pointPaint);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/SmoothBezierSplineInterpolation.cpp b/docs/examples/SmoothBezierSplineInterpolation.cpp
new file mode 100644
index 0000000..4486815
--- /dev/null
+++ b/docs/examples/SmoothBezierSplineInterpolation.cpp
@@ -0,0 +1,82 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(SmoothBezierSplineInterpolation, 1024, 1024, false, 0) {
+// Smooth Bézier Spline Interpolation
+
+SkPath MakeCubicSplineInterpolation(const SkPoint* pts, size_t N) {
+ // Code borrowed from https://www.particleincell.com/2012/bezier-splines/
+
+ SkPath path;
+ if (N < 2) {
+ return path;
+ }
+ if (N == 2) {
+ path.moveTo(pts[0]);
+ path.lineTo(pts[1]);
+ return path;
+ }
+ size_t n = N - 1; // number of segments
+ struct Scratch {
+ SkPoint a, b, c, r, p;
+ };
+ // Can I do this will less allocation?
+ std::unique_ptr<Scratch[]> s(new Scratch[n]);
+ s[0].a = {0, 0};
+ s[0].b = {2, 2};
+ s[0].c = {1, 1};
+ s[0].r = {pts[0].x() + 2 * pts[1].x(), pts[0].y() + 2 * pts[1].y()};
+ for (size_t i = 1; i < n - 1; ++i) {
+ s[i].a = {1, 1};
+ s[i].b = {4, 4};
+ s[i].c = {1, 1};
+ s[i].r = {4 * pts[i].x() + 2 * pts[i + 1].x(), 4 * pts[i].y() + 2 * pts[i + 1].y()};
+ }
+ s[n - 1].a = {2, 2};
+ s[n - 1].b = {7, 7};
+ s[n - 1].c = {0, 0};
+ s[n - 1].r = {8 * pts[n - 1].x() + pts[N - 1].x(), 8 * pts[n - 1].y() + pts[N - 1].y()};
+ for (size_t i = 1; i < n; i++) {
+ float mx = s[i].a.x() / s[i - 1].b.x();
+ float my = s[i].a.y() / s[i - 1].b.y();
+ s[i].b -= {mx * s[i - 1].c.x(), my * s[i - 1].c.y()};
+ s[i].r -= {mx * s[i - 1].r.x(), my * s[i - 1].r.y()};
+ }
+ s[n - 1].p = {s[n - 1].r.x() / s[n - 1].b.x(), s[n - 1].r.y() / s[n - 1].b.y()};
+ for (int i = (int)N - 3; i >= 0; --i) {
+ s[i].p = {(s[i].r.x() - s[i].c.x() * s[i + 1].p.fX) / s[i].b.x(),
+ (s[i].r.y() - s[i].c.y() * s[i + 1].p.fY) / s[i].b.y()};
+ }
+
+ path.moveTo(pts[0]);
+ for (size_t i = 0; i < n - 1; i++) {
+ SkPoint q = {2 * pts[i + 1].x() - s[i + 1].p.fX, 2 * pts[i + 1].y() - s[i + 1].p.fY};
+ path.cubicTo(s[i].p, q, pts[i + 1]);
+ }
+ SkPoint q = {0.5f * (pts[N - 1].x() + s[n - 1].p.x()),
+ 0.5f * (pts[N - 1].y() + s[n - 1].p.y())};
+ path.cubicTo(s[n - 1].p, q, pts[n]);
+ return path;
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(3);
+ p.setStrokeCap(SkPaint::kRound_Cap);
+
+ // randomly generated y values in range [12,1024].
+ SkPoint pts[] = {
+ {62, 511}, {162, 605}, {262, 610}, {362, 402}, {462, 959},
+ {562, 58}, {662, 272}, {762, 99}, {862, 759}, {962, 945},
+ };
+
+ canvas->drawPath(MakeCubicSplineInterpolation(pts, SK_ARRAY_COUNT(pts)), p);
+
+ p.setStrokeWidth(10);
+ p.setColor(SK_ColorBLACK);
+ canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(pts), pts, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/UnicornPoop.cpp b/docs/examples/UnicornPoop.cpp
new file mode 100644
index 0000000..0540f7e
--- /dev/null
+++ b/docs/examples/UnicornPoop.cpp
@@ -0,0 +1,20 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(UnicornPoop, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(10);
+
+ for (int r = 0; r <= 255; r += 10) {
+ for (int g = 0; g <= 255; g += 10) {
+ for (int b = 0; b <= 255; b += 10) {
+ p.setColor(SkColorSetRGB(r, g, b));
+ canvas->drawRect(SkRect::MakeXYWH(r, g, b, 1), p);
+ }
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/UnpremulBugs.cpp b/docs/examples/UnpremulBugs.cpp
new file mode 100644
index 0000000..6aa9ad6
--- /dev/null
+++ b/docs/examples/UnpremulBugs.cpp
@@ -0,0 +1,53 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(UnpremulBugs, 400, 400, false, 6) {
+void fill(SkBitmap & b, SkColor c, int n) {
+ for (int y = 0; y < n; y++) {
+ for (int x = 0; x < n; x++) {
+ *(b.getAddr32(x, y)) = c;
+ }
+ }
+}
+
+void doCell(SkCanvas* canvas, float x, float y, SkAlphaType at, SkColor c, int n) {
+ SkImageInfo info = SkImageInfo::MakeS32(n, n, at);
+ SkBitmap bmp;
+ bmp.allocPixels(info);
+ fill(bmp, c, n);
+ sk_sp<SkImage> img = SkImage::MakeFromBitmap(bmp);
+
+ SkPaint paint;
+ const SkTileMode tile = SkTileMode::kRepeat;
+
+ paint.setShader(img->makeShader(tile, tile, nullptr));
+ canvas->drawRect(SkRect::MakeXYWH(x, y, 50, 50), paint);
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorBLACK);
+
+ doCell(canvas, 0, 0, kPremul_SkAlphaType, 0x80404040, 2);
+ doCell(canvas, 0, 50, kUnpremul_SkAlphaType, 0x80808080, 2);
+ doCell(canvas, 50, 0, kPremul_SkAlphaType, 0x80808080, 2);
+ doCell(canvas, 50, 50, kUnpremul_SkAlphaType, 0x80FFFFFF, 2);
+
+ doCell(canvas, 110, 0, kPremul_SkAlphaType, 0x80404040, 1);
+ doCell(canvas, 110, 50, kUnpremul_SkAlphaType, 0x80808080, 1);
+ doCell(canvas, 160, 0, kPremul_SkAlphaType, 0x80808080, 1);
+ doCell(canvas, 160, 50, kUnpremul_SkAlphaType, 0x80FFFFFF, 1);
+
+ SkFont font(nullptr, 12);
+ SkPaint paint;
+ paint.setColor(SK_ColorWHITE);
+ canvas->drawString("Premul", 220, 20, font, paint);
+ canvas->drawString("Unpremul", 220, 70, font, paint);
+ canvas->drawString("Gray", 5, 120, font, paint);
+ canvas->drawString("White", 55, 120, font, paint);
+ canvas->drawString("Gray", 115, 120, font, paint);
+ canvas->drawString("White", 165, 120, font, paint);
+
+ canvas->drawString("2x2", 40, 150, font, paint);
+ canvas->drawString("1x1", 150, 150, font, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/UnpremulGPU.cpp b/docs/examples/UnpremulGPU.cpp
new file mode 100644
index 0000000..cf3afd7
--- /dev/null
+++ b/docs/examples/UnpremulGPU.cpp
@@ -0,0 +1,35 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(UnpremulGPU, 256, 256, false, 6) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(0xffa020a0);
+ SkImageInfo premulInfo = SkImageInfo::MakeS32(10, 10, kPremul_SkAlphaType);
+ SkBitmap premulBitmap;
+ premulBitmap.allocPixels(premulInfo);
+ for (int y = 0; y < 10; y++) {
+ for (int x = 0; x < 10; x++) {
+ *(premulBitmap.getAddr32(x, y)) = 0x80808080;
+ }
+ }
+ sk_sp<SkImage> premulImage = SkImage::MakeFromBitmap(premulBitmap);
+
+ SkImageInfo unpremulInfo = premulInfo.makeAlphaType(kUnpremul_SkAlphaType);
+ SkBitmap unpremulBitmap;
+ unpremulBitmap.allocPixels(unpremulInfo);
+ for (int y = 0; y < 10; y++) {
+ for (int x = 0; x < 10; x++) {
+ *(unpremulBitmap.getAddr32(x, y)) = 0x80FFFFFF;
+ }
+ }
+ sk_sp<SkImage> unpremulImage = SkImage::MakeFromBitmap(unpremulBitmap);
+
+ SkPaint paint;
+ const SkTileMode tile = SkTileMode::kRepeat;
+ paint.setShader(premulImage->makeShader(tile, tile, nullptr));
+ canvas->drawCircle(10.0f, 10.0f, 10.0f, paint);
+
+ paint.setShader(unpremulImage->makeShader(tile, tile, nullptr));
+ canvas->drawCircle(10.0f, 35.0f, 10.0f, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/alpha_bitmap_color_filter_mask_filter.cpp b/docs/examples/alpha_bitmap_color_filter_mask_filter.cpp
new file mode 100644
index 0000000..4af0645
--- /dev/null
+++ b/docs/examples/alpha_bitmap_color_filter_mask_filter.cpp
@@ -0,0 +1,45 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(alpha_bitmap_color_filter_mask_filter, 256, 256, false, 0) {
+static SkBitmap make_alpha_image(int w, int h) {
+ SkBitmap bm;
+ bm.allocPixels(SkImageInfo::MakeA8(w, h));
+ bm.eraseARGB(10, 0, 0, 0);
+ for (int y = 0; y < bm.height(); ++y) {
+ for (int x = y; x < bm.width(); ++x) {
+ *bm.getAddr8(x, y) = 0xFF;
+ }
+ }
+ bm.setImmutable();
+ return bm;
+}
+
+static sk_sp<SkColorFilter> make_color_filter() {
+ SkScalar colorMatrix[20] = {
+ 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 0.5, 0.5, 0,
+ 0, 0, 0.5, 0.5, 0}; // mix G and A.
+ return SkColorFilters::Matrix(colorMatrix);
+}
+
+void draw(SkCanvas* canvas) {
+ auto image = SkImage::MakeFromBitmap(make_alpha_image(96, 96));
+ SkPaint paint;
+
+ paint.setColorFilter(make_color_filter());
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 10.0f, false));
+ canvas->drawImage(image.get(), 16, 16, &paint);
+
+ paint.setColorFilter(nullptr);
+ paint.setShader(SkShaders::Color(SK_ColorCYAN));
+ canvas->drawImage(image.get(), 144, 16, &paint);
+
+ paint.setColorFilter(make_color_filter());
+ canvas->drawImage(image.get(), 16, 144, &paint);
+
+ paint.setMaskFilter(nullptr);
+ canvas->drawImage(image.get(), 144, 144, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/alphaimage_shader_colorfilter.cpp b/docs/examples/alphaimage_shader_colorfilter.cpp
new file mode 100644
index 0000000..8a5af29
--- /dev/null
+++ b/docs/examples/alphaimage_shader_colorfilter.cpp
@@ -0,0 +1,31 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(alphaimage_shader_colorfilter, 256, 256, false, 0) {
+sk_sp<SkImage> alpha_image() {
+ auto s = SkSurface::MakeRaster(SkImageInfo::MakeA8(64, 64));
+ s->getCanvas()->clear(SkColorSetARGB(0x80, 0x00, 0x00, 0x00));
+ return s->makeImageSnapshot();
+}
+sk_sp<SkShader> linear_gradient() {
+ SkPoint gpts[2] = {{0, 0}, {64, 64}};
+ SkColor gc[3] = {SK_ColorRED, SK_ColorGREEN, SK_ColorMAGENTA};
+ return SkGradientShader::MakeLinear(gpts, gc, nullptr, 3, (SkTileMode)0);
+}
+sk_sp<SkColorFilter> color_filter() {
+ SkScalar colorMatrix[20] = {
+ 1, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 0, 1, 0};
+ return SkColorFilters::Matrix(colorMatrix);
+}
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setShader(linear_gradient());
+ p.setColorFilter(color_filter());
+ auto i = alpha_image();
+ canvas->scale(2, 2);
+ canvas->drawImage(i.get(), 32, 32, &p);
+}
+} // END FIDDLE
diff --git a/docs/examples/backdrop_blur_with_rrect_clip.cpp b/docs/examples/backdrop_blur_with_rrect_clip.cpp
new file mode 100644
index 0000000..5f4df3f
--- /dev/null
+++ b/docs/examples/backdrop_blur_with_rrect_clip.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(backdrop_blur_with_rrect_clip, 512, 512, false, 3) {
+void draw(SkCanvas* canvas) {
+ const SkRect r = SkRect::MakeXYWH(128, 128, 256, 256);
+ const SkRRect rr = SkRRect::MakeRectXY(r, 128, 128);
+
+ canvas->drawImage(image, 0, 0);
+
+ canvas->save();
+ canvas->clipRRect(rr, true);
+
+ sk_sp<SkImageFilter> filter = SkBlurImageFilter::Make(10, 10, nullptr);
+ SkPaint p;
+ p.setImageFilter(std::move(filter));
+
+ SkCanvas::SaveLayerRec slr(&r, &p, SkCanvas::kInitWithPrevious_SaveLayerFlag);
+ canvas->saveLayer(slr);
+ canvas->drawColor(0x40FFFFFF);
+ canvas->restore();
+ canvas->restore();
+}
+} // END FIDDLE
diff --git a/docs/examples/bezier_curves.cpp b/docs/examples/bezier_curves.cpp
new file mode 100644
index 0000000..d0f9248
--- /dev/null
+++ b/docs/examples/bezier_curves.cpp
@@ -0,0 +1,21 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(bezier_curves, 256, 256, false, 5) {
+void draw(SkCanvas* canvas) {
+ canvas->drawColor(SK_ColorWHITE);
+
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(8);
+ paint.setColor(0xff4285F4);
+ paint.setAntiAlias(true);
+ paint.setStrokeCap(SkPaint::kRound_Cap);
+
+ SkPath path;
+ path.moveTo(10, 10);
+ path.quadTo(256, 64, 128, 128);
+ path.quadTo(10, 192, 250, 250);
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/blur4444.cpp b/docs/examples/blur4444.cpp
new file mode 100644
index 0000000..932cb68
--- /dev/null
+++ b/docs/examples/blur4444.cpp
@@ -0,0 +1,62 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(blur4444, 650, 480, false, 0) {
+void draw(SkCanvas* canvas) {
+ bool forceRaster = false;
+ bool dither = false;
+ bool postDither = false;
+
+ canvas->clear(SK_ColorTRANSPARENT);
+ SkPaint grayPaint;
+ grayPaint.setColor(SK_ColorGRAY);
+ SkPaint ltGrayPaint;
+ ltGrayPaint.setColor(SK_ColorLTGRAY);
+ canvas->drawRect({350, 0, 400, 480}, ltGrayPaint);
+ canvas->drawRect({400, 0, 500, 480}, grayPaint);
+ canvas->drawRect({500, 0, 640, 480}, SkPaint());
+ canvas->drawRect({0, 200, 320, 215}, ltGrayPaint);
+ canvas->drawRect({0, 215, 320, 230}, grayPaint);
+ canvas->drawRect({0, 230, 320, 250}, SkPaint());
+
+ sk_sp<SkSurface> surf;
+ auto ii = SkImageInfo::Make(650, 480, kARGB_4444_SkColorType, kPremul_SkAlphaType);
+ if (canvas->getGrContext() && !forceRaster) {
+ surf = SkSurface::MakeRenderTarget(canvas->getGrContext(), SkBudgeted::kNo, ii);
+ } else {
+ surf = SkSurface::MakeRaster(ii);
+ }
+ if (!surf) {
+ return;
+ }
+
+ auto c = surf->getCanvas();
+ c->clear(SK_ColorTRANSPARENT);
+
+ SkPaint blrPaint;
+ blrPaint.setAntiAlias(true);
+ blrPaint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 12.047));
+ blrPaint.setFilterQuality(kLow_SkFilterQuality);
+ blrPaint.setBlendMode(SkBlendMode::kSrc);
+ blrPaint.setDither(dither);
+
+ blrPaint.setColor(SK_ColorWHITE);
+ c->drawRect(SkRect{0, 20, 640, 104}, blrPaint);
+
+ blrPaint.setColor(SkColorSetARGB(255, 247, 247, 247));
+ c->drawRect(SkRect{0, 0, 640, 84}.makeOffset(0, 300), blrPaint);
+
+ static constexpr SkColor colors[]{SkColorSetARGB(255, 247, 247, 247), 0};
+ static constexpr SkPoint pts[]{{0.5, 0}, {256.5, 0}};
+ auto grd = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
+ SkPaint grdPaint;
+ grdPaint.setShader(grd);
+ grdPaint.setDither(dither);
+
+ c->drawRect(SkRect{0, 0, 640, 100}.makeOffset(0, 150), grdPaint);
+
+ SkPaint postPaint;
+ postPaint.setDither(postDither);
+ surf->draw(canvas, 0, 0, &postPaint);
+}
+} // END FIDDLE
diff --git a/docs/examples/blur_alpha_img.cpp b/docs/examples/blur_alpha_img.cpp
new file mode 100644
index 0000000..880f018
--- /dev/null
+++ b/docs/examples/blur_alpha_img.cpp
@@ -0,0 +1,36 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(blur_alpha_img, 256, 256, false, 0) {
+sk_sp<SkImage> foo() {
+ int w = 240, h = 240;
+ SkScalar scale = 10.0f;
+ SkPath path;
+ static const int8_t pts[] = {2, 2, 1, 3, 0, 3, 2, 1, 3, 1, 4, 0, 4, 1,
+ 5, 1, 4, 2, 4, 3, 2, 5, 2, 4, 3, 3, 2, 3};
+ path.moveTo(2 * scale, 3 * scale);
+ for (size_t i = 0; i < sizeof(pts) / sizeof(pts[0]); i += 2) {
+ path.lineTo(pts[i] * scale, pts[i + 1] * scale);
+ }
+ path.close();
+ SkMatrix matrix = SkMatrix::MakeScale(4 * scale);
+ SkPaint paint;
+ paint.setPathEffect(SkPath2DPathEffect::Make(matrix, path));
+ paint.setAntiAlias(true);
+ SkRect bounds{-4 * scale, -4 * scale, (float)w, (float)h};
+ SkBitmap bm;
+ bm.allocPixels(SkImageInfo::MakeA8(w, h));
+ SkCanvas c(bm);
+ c.clear(0);
+ c.drawRect(bounds, paint);
+ return SkImage::MakeFromBitmap(bm);
+}
+
+void draw(SkCanvas* canvas) {
+ auto a8img = foo();
+ SkPaint paint;
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 2.0f, 0));
+ paint.setColor(0xFF008000);
+ canvas->drawImage(a8img, 8, 8, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/blurbug.cpp b/docs/examples/blurbug.cpp
new file mode 100644
index 0000000..4babf82
--- /dev/null
+++ b/docs/examples/blurbug.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(blurbug, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ uint8_t pixels[][8] = {{0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
+ {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00},
+ {0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00},
+ {0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
+ {0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00}};
+ SkBitmap bitmap;
+ bitmap.installPixels(SkImageInfo::MakeA8(8, 8), (void*)pixels, sizeof(pixels[0]));
+ SkPaint paint;
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kSolid_SkBlurStyle, 3));
+ for (auto color : {SK_ColorRED, SK_ColorBLUE, 0xFF007F00}) {
+ paint.setColor(color);
+ canvas->drawBitmapRect(bitmap, SkRect::MakeWH(8, 8), SkRect::MakeWH(32, 32), &paint);
+ canvas->translate(48, 0);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/bug5252.cpp b/docs/examples/bug5252.cpp
new file mode 100644
index 0000000..84efdcc
--- /dev/null
+++ b/docs/examples/bug5252.cpp
@@ -0,0 +1,34 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(bug5252, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
+
+ SkPath clip1;
+ clip1.addOval(SkRect::MakeWH(225, 200));
+ canvas->clipPath(clip1); // bug
+
+ SkPath clip2;
+ clip2.addRect(SkRect::MakeWH(220, 200));
+ // canvas->clipPath(clip2); // ok
+
+ SkPaint pa;
+ pa.setStyle(SkPaint::kStroke_Style);
+ pa.setAntiAlias(true);
+ pa.setStrokeWidth(1.0f);
+ for (int i = 0; i < 15; i++) {
+ for (int j = 0; j < 10; j++) {
+ SkAutoCanvasRestore acs(canvas, true);
+
+ canvas->translate(i * 15, j * 20);
+ canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 15), pa);
+ SkPath path;
+ path.moveTo(6, 6);
+ path.cubicTo(14, 10, 13, 12, 10, 12);
+ path.cubicTo(7, 15, 8, 17, 14, 18);
+ canvas->drawPath(path, pa);
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/bug583299.cpp b/docs/examples/bug583299.cpp
new file mode 100644
index 0000000..5f0b4c3
--- /dev/null
+++ b/docs/examples/bug583299.cpp
@@ -0,0 +1,848 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(bug583299, 350, 256, false, 0) {
+struct PieWedge {
+ double fMove[2];
+ double fLine1[2];
+ double fArc1Angles[2];
+ double fLine2[2];
+ double fArc2Angles[2];
+ unsigned char fRGB[3];
+} wedges[] = {
+ {{209, 62},
+ {208.99999999999997, 15},
+ {4.71238898038469, 4.864188625411087},
+ {214.8974757323885, 62.4484788888183},
+ {4.864188625411087, 4.71238898038469},
+ {66, 165, 245}},
+ {{214.8974757323885, 62.4484788888183},
+ {222.00469007654902, 15.988953447137789},
+ {4.864188625411087, 5.939986109728601},
+ {245.72563512075425, 87.87644388981317},
+ {5.939986109728601, 4.864188625411087},
+ {239, 83, 80}},
+ {{245.72563512075425, 87.87644388981317},
+ {289.9847338560222, 72.06087626984443},
+ {5.939986109728601, 0.6071985801055906},
+ {241.02873602896423, 123.25219244000306},
+ {0.6071985801055906, 5.939986109728601},
+ {255, 202, 40}},
+ {{241.02873602896423, 123.25219244000306},
+ {279.62746919207495, 150.06893717539134},
+ {0.6071985801055906, 1.2143971602111803},
+ {222.6071759801575, 137.54921013982414},
+ {1.2143971602111803, 0.6071985801055906},
+ {102, 187, 106}},
+ {{222.6071759801575, 137.54921013982414},
+ {239.00556754598836, 181.59569415448402},
+ {1.2143971602111803, 1.5905962804939922},
+ {208.2278522599403, 139.99235550550287},
+ {1.5905962804939922, 1.2143971602111803},
+ {171, 71, 188}},
+ {{208.2278522599403, 139.99235550550287},
+ {207.29731523986837, 186.98314290957046},
+ {1.5905962804939922, 1.8479956785822313},
+ {198.32714338718876, 138.51120008373994},
+ {1.8479956785822313, 1.5905962804939922},
+ {38, 198, 218}},
+ {{198.32714338718876, 138.51120008373994},
+ {185.46498285380088, 183.71700531286245},
+ {1.8479956785822313, 2.0657951692722794},
+ {190.473805325209, 135.3188011281243},
+ {2.0657951692722794, 1.8479956785822313},
+ {255, 110, 64}},
+ {{190.47380532520896, 135.31880112812428},
+ {168.1473655889223, 176.6773563338125},
+ {2.065795169272281, 2.296794629095059},
+ {183.10858870915067, 130.16564453887622},
+ {2.296794629095059, 2.065795169272281},
+ {212, 225, 87}},
+ {{183.10858870915067, 130.16564453887622},
+ {151.90611869197326, 165.31398539341933},
+ {2.296794629095059, 2.461794243254186},
+ {178.66972101612106, 125.51681416416235},
+ {2.461794243254186, 2.296794629095059},
+ {189, 189, 189}},
+ {{178.66972101612106, 125.51681416416235},
+ {142.1178463432413, 155.06271841328106},
+ {2.461794243254186, 2.5937939345814893},
+ {175.7067515538738, 121.31156340374902},
+ {2.5937939345814893, 2.461794243254186},
+ {92, 107, 192}},
+ {{175.70675155387386, 121.31156340374908},
+ {135.58411881110644, 145.78960135185693},
+ {2.5937939345814875, 2.719193641342425},
+ {173.4277844354395, 116.98804177591612},
+ {2.719193641342425, 2.5937939345814875},
+ {79, 195, 247}},
+ {{173.4277844354395, 116.98804177591612},
+ {130.55870413968708, 136.25568186484068},
+ {2.719193641342425, 2.831393378970633},
+ {171.86136233918353, 112.90468784549111},
+ {2.831393378970633, 2.719193641342425},
+ {255, 167, 38}},
+ {{171.86136233918353, 112.90468784549111},
+ {127.104542594097, 127.25136294133937},
+ {2.831393378970633, 2.9435931165988407},
+ {170.76198015985182, 108.67162555814826},
+ {2.9435931165988407, 2.831393378970633},
+ {66, 165, 245}},
+ {{170.76198015985182, 108.67162555814826},
+ {124.68026394223733, 117.91691789745515},
+ {2.9435931165988407, 2.99639299312976},
+ {170.41039556773984, 106.64290968930811},
+ {2.99639299312976, 2.9435931165988407},
+ {239, 83, 80}},
+ {{170.41039556773984, 106.64290968930811},
+ {123.90497484168273, 113.44333931488454},
+ {2.99639299312976, 3.095392761625238},
+ {170.04161398270747, 102.80115488718383},
+ {3.095392761625238, 2.99639299312976},
+ {255, 202, 40}},
+ {{170.04161398270747, 102.80115488718383},
+ {123.09176416699597, 104.97177744353357},
+ {3.095392761625238, 3.194392530120716},
+ {170.05434999746018, 98.9417614619119},
+ {3.194392530120716, 3.095392761625238},
+ {102, 187, 106}},
+ {{170.05434999746018, 98.94176146191197},
+ {123.1198487123481, 96.46132014678024},
+ {3.194392530120714, 3.2735923449170947},
+ {170.33927335887392, 95.86694870665369},
+ {3.2735923449170947, 3.194392530120714},
+ {171, 71, 188}},
+ {{170.33927335887392, 95.86694870665369},
+ {123.74814125290146, 89.68096381467222},
+ {3.2735923449170947, 3.352792159713477},
+ {170.86657367205342, 92.82431675692668},
+ {3.352792159713477, 3.2735923449170947},
+ {38, 198, 218}},
+ {{170.86657367205342, 92.82431675692668},
+ {124.9109060460665, 82.97157028450496},
+ {3.352792159713477, 3.412192020810762},
+ {171.41917672588357, 90.57494738432324},
+ {3.412192020810762, 3.352792159713477},
+ {255, 110, 64}},
+ {{171.41917672588357, 90.57494738432324},
+ {126.12946662630736, 78.0114224372256},
+ {3.412192020810762, 3.471591881908047},
+ {172.1043388501384, 88.36235036430459},
+ {3.471591881908047, 3.412192020810762},
+ {212, 225, 87}},
+ {{172.1043388501384, 88.36235036430453},
+ {127.64033695158726, 73.13236234179972},
+ {3.471591881908049, 3.5375917275716997},
+ {173.01814557458636, 85.9565246000686},
+ {3.5375917275716997, 3.471591881908049},
+ {189, 189, 189}},
+ {{173.01814557458636, 85.9565246000686},
+ {129.65539793370326, 67.82720809245897},
+ {3.5375917275716997, 3.5441917121380655},
+ {173.11821523751334, 85.71937428445484},
+ {3.5441917121380655, 3.5375917275716997},
+ {92, 107, 192}},
+ {{173.11821523751334, 85.71937428445484},
+ {129.8760643699012, 67.30426124264403},
+ {3.5441917121380655, 3.5969915886689847},
+ {173.97466004891183, 83.84699556023183},
+ {3.5969915886689847, 3.5441917121380655},
+ {79, 195, 247}},
+ {{173.97466004891183, 83.84699556023183},
+ {131.7646349796517, 63.17542610717788},
+ {3.5969915886689847, 3.6497914651999075},
+ {174.9287267647916, 82.02242533589258},
+ {3.6497914651999075, 3.5969915886689847},
+ {255, 167, 38}},
+ {{174.9287267647916, 82.02242533589258},
+ {133.86847440441224, 59.15201484325031},
+ {3.6497914651999075, 3.689391372598097},
+ {175.7067515538738, 80.688436596251},
+ {3.689391372598097, 3.6497914651999075},
+ {66, 165, 245}},
+ {{175.70675155387386, 80.68843659625094},
+ {135.5841188111064, 56.210398648143084},
+ {3.6893913725980987, 3.728991279996288},
+ {176.53697841699477, 79.38629532677618},
+ {3.728991279996288, 3.6893913725980987},
+ {239, 83, 80}},
+ {{176.53697841699477, 79.38629532677618},
+ {137.41487548362952, 53.33901020776284},
+ {3.728991279996288, 3.7619912028281135},
+ {177.26777398454274, 78.32698008416307},
+ {3.7619912028281135, 3.728991279996288},
+ {255, 202, 40}},
+ {{177.26777398454274, 78.32698008416307},
+ {139.0263734018122, 51.003084288154476},
+ {3.7619912028281135, 3.788391141093573},
+ {177.87732813607064, 77.49724918120904},
+ {3.788391141093573, 3.7619912028281135},
+ {102, 187, 106}},
+ {{177.87732813607064, 77.49724918120904},
+ {140.37051845389936, 49.17342127138402},
+ {3.788391141093573, 3.8147910793590345},
+ {178.50857218374682, 76.68389772750939},
+ {3.8147910793590345, 3.788391141093573},
+ {171, 71, 188}},
+ {{178.50857218374682, 76.68389772750939},
+ {141.7624925077494, 47.379877040148926},
+ {3.8147910793590345, 3.83459103305813},
+ {178.99597513166773, 76.0849745795735},
+ {3.83459103305813, 3.8147910793590345},
+ {38, 198, 218}},
+ {{178.99597513166773, 76.0849745795735},
+ {142.83727849547242, 46.05917471393132},
+ {3.83459103305813, 3.8543909867572257},
+ {179.49514041820387, 75.49581875341823},
+ {3.8543909867572257, 3.83459103305813},
+ {255, 110, 64}},
+ {{179.49514041820387, 75.49581875341823},
+ {143.93800194783418, 44.76001058446072},
+ {3.8543909867572257, 3.8741909404563213},
+ {180.0058723579047, 74.91666121306773},
+ {3.8741909404563213, 3.8543909867572257},
+ {212, 225, 87}},
+ {{180.00587235790465, 74.91666121306778},
+ {145.0642313533282, 43.482893957021275},
+ {3.8741909404563195, 3.893990894155415},
+ {180.52797073089823, 74.34772900296463},
+ {3.893990894155415, 3.8741909404563195},
+ {189, 189, 189}},
+ {{180.52797073089823, 74.34772900296463},
+ {146.21552520146793, 42.22832549371687},
+ {3.893990894155415, 3.9137908478545107},
+ {181.06123086138257, 73.78924515896263},
+ {3.9137908478545107, 3.893990894155415},
+ {92, 107, 192}},
+ {{181.06123086138257, 73.78924515896263},
+ {147.39143215586927, 40.996797017199654},
+ {3.9137908478545107, 3.9335908015536063},
+ {181.60544369786365, 73.24142862089114},
+ {3.9335908015536063, 3.9137908478545107},
+ {79, 195, 247}},
+ {{181.60544369786365, 73.24142862089114},
+ {148.59149123118652, 39.78879131786252},
+ {3.9335908015536063, 3.953390755252702},
+ {182.16039589510896, 72.70449414672505},
+ {3.953390755252702, 3.9335908015536063},
+ {255, 167, 38}},
+ {{182.16039589510896, 72.70449414672505},
+ {149.81523197383004, 38.604781964573206},
+ {3.953390755252702, 3.9731907089517975},
+ {182.72586989778426, 72.1786522283943},
+ {3.9731907089517975, 3.953390755252702},
+ {66, 165, 245}},
+ {{182.72586989778426, 72.1786522283943},
+ {151.0621746463961, 37.44523311902331},
+ {3.9731907089517975, 3.9863906780845255},
+ {183.1085887091506, 71.83435546112383},
+ {3.9863906780845255, 3.9731907089517975},
+ {239, 83, 80}},
+ {{183.10858870915067, 71.83435546112379},
+ {151.90611869197326, 36.68601460658067},
+ {3.9863906780845273, 3.999590647217257},
+ {183.49581875341823, 71.49514041820387},
+ {3.999590647217257, 3.9863906780845273},
+ {255, 202, 40}},
+ {{183.49581875341823, 71.49514041820387},
+ {152.7600105844607, 35.938001947834195},
+ {3.999590647217257, 4.012790616349987},
+ {183.88749256091927, 71.161066203329},
+ {4.012790616349987, 3.999590647217257},
+ {102, 187, 106}},
+ {{183.8874925609193, 71.16106620332897},
+ {153.6237015445913, 35.20132547400746},
+ {4.012790616349989, 4.025990585482717},
+ {184.28354188771962, 70.83219102447296},
+ {4.025990585482717, 4.012790616349989},
+ {171, 71, 188}},
+ {{184.28354188771968, 70.83219102447292},
+ {154.49704108574082, 34.47611354114541},
+ {4.0259905854827185, 4.039190554615448},
+ {184.6838977275094, 70.50857218374685},
+ {4.039190554615448, 4.0259905854827185},
+ {38, 198, 218}},
+ {{184.6838977275094, 70.50857218374685},
+ {155.3798770401489, 33.76249250774944},
+ {4.039190554615448, 4.052390523748178},
+ {185.08849032362605, 70.19026606741508},
+ {4.052390523748178, 4.039190554615448},
+ {255, 110, 64}},
+ {{185.0884903236261, 70.19026606741504},
+ {156.2720555854319, 33.06058671276138},
+ {4.05239052374818, 4.065590492880908},
+ {185.49724918120899, 69.87732813607067},
+ {4.065590492880908, 4.05239052374818},
+ {212, 225, 87}},
+ {{185.49724918120899, 69.87732813607067},
+ {157.1734212713839, 32.37051845389945},
+ {4.065590492880908, 4.0787904620136395},
+ {185.91010307948213, 69.56981291497203},
+ {4.0787904620136395, 4.065590492880908},
+ {189, 189, 189}},
+ {{185.91010307948213, 69.56981291497203},
+ {158.08381704706312, 31.692407966348583},
+ {4.0787904620136395, 4.091990431146369},
+ {186.32698008416307, 69.26777398454276},
+ {4.091990431146369, 4.0787904620136395},
+ {92, 107, 192}},
+ {{186.32698008416307, 69.26777398454276},
+ {159.00308428815444, 31.026373401812222},
+ {4.091990431146369, 4.105190400279099},
+ {186.74780755999694, 68.97126397103578},
+ {4.105190400279099, 4.091990431146369},
+ {79, 195, 247}},
+ {{186.74780755999694, 68.97126397103578},
+ {159.93106282460863, 30.37253080792506},
+ {4.105190400279099, 4.118390369411829},
+ {187.17251218341195, 68.68033453736409},
+ {4.118390369411829, 4.105190400279099},
+ {255, 167, 38}},
+ {{187.172512183412, 68.68033453736405},
+ {160.86759096854956, 29.730994108033556},
+ {4.118390369411831, 4.131590338544559},
+ {187.60101995529507, 68.3950363740991},
+ {4.131590338544559, 4.118390369411831},
+ {66, 165, 245}},
+ {{187.60101995529507, 68.3950363740991},
+ {161.81250554244556, 29.101875081346734},
+ {4.131590338544559, 4.14479030767729},
+ {188.0332562138855, 68.11541919063848},
+ {4.14479030767729, 4.131590338544559},
+ {239, 83, 80}},
+ {{188.0332562138855, 68.11541919063848},
+ {162.76564190754235, 28.4852833434592},
+ {4.14479030767729, 4.151390292243654},
+ {188.25074901590185, 67.97775623009694},
+ {4.151390292243654, 4.14479030767729},
+ {255, 202, 40}},
+ {{188.25074901590185, 67.97775623009694},
+ {163.24524141968098, 28.181718866367618},
+ {4.151390292243654, 4.15799027681002},
+ {188.4691456477831, 67.84153170654506},
+ {4.15799027681002, 4.151390292243654},
+ {102, 187, 106}},
+ {{188.4691456477831, 67.84153170654506},
+ {163.72683399254737, 27.88132632725319},
+ {4.15799027681002, 4.164590261376386},
+ {188.688436596251, 67.70675155387381},
+ {4.164590261376386, 4.15799027681002},
+ {171, 71, 188}},
+ {{188.688436596251, 67.70675155387381},
+ {164.21039864814318, 27.584118811106364},
+ {4.164590261376386, 4.17119024594275},
+ {188.90861230907103, 67.57342164305794},
+ {4.17119024594275, 4.164590261376386},
+ {38, 198, 218}},
+ {{188.90861230907103, 67.57342164305794},
+ {164.6959143225669, 27.290109264179037},
+ {4.17119024594275, 4.177790230509116},
+ {189.129663195469, 67.44154778190001},
+ {4.177790230509116, 4.17119024594275},
+ {255, 110, 64}},
+ {{189.129663195469, 67.44154778190001},
+ {165.1833598669316, 26.999310493420538},
+ {4.177790230509116, 4.1843902150754815},
+ {189.35157962654816, 67.31113571477775},
+ {4.1843902150754815, 4.177790230509116},
+ {212, 225, 87}},
+ {{189.35157962654816, 67.31113571477775},
+ {165.6727140482857, 26.711735165920174},
+ {4.1843902150754815, 4.1909901996418455},
+ {189.57435193570907, 67.18219112239366},
+ {4.1909901996418455, 4.1843902150754815},
+ {189, 189, 189}},
+ {{189.57435193570907, 67.18219112239366},
+ {166.16395555053796, 26.427395808355243},
+ {4.1909901996418455, 4.1975901842082095},
+ {189.7979704190706, 67.05471962152747},
+ {4.1975901842082095, 4.1909901996418455},
+ {92, 107, 192}},
+ {{189.7979704190706, 67.05471962152747},
+ {166.65706297538645, 26.146304806445187},
+ {4.1975901842082095, 4.204190168774575},
+ {190.02242533589256, 66.9287267647916},
+ {4.204190168774575, 4.1975901842082095},
+ {79, 195, 247}},
+ {{190.02242533589262, 66.92872676479158},
+ {167.1520148432504, 25.868474404412183},
+ {4.204190168774577, 4.210790153340941},
+ {190.247706909, 66.80421804038936},
+ {4.210790153340941, 4.204190168774577},
+ {255, 167, 38}},
+ {{190.247706909, 66.80421804038936},
+ {167.64878959420508, 25.593916704448333},
+ {4.210790153340941, 4.217390137907305},
+ {190.47380532520896, 66.68119887187574},
+ {4.217390137907305, 4.210790153340941},
+ {66, 165, 245}},
+ {{190.47380532520896, 66.68119887187574},
+ {168.1473655889223, 25.322643666187517},
+ {4.217390137907305, 4.223990122473671},
+ {190.7007107357544, 66.55967461792113},
+ {4.223990122473671, 4.217390137907305},
+ {239, 83, 80}},
+ {{190.70071073575446, 66.5596746179211},
+ {168.6477211096124, 25.054667106185008},
+ {4.223990122473673, 4.230590107040037},
+ {190.9284132567187, 66.43965057207814},
+ {4.230590107040037, 4.223990122473673},
+ {255, 202, 40}},
+ {{190.9284132567187, 66.43965057207814},
+ {169.14983436096944, 24.789998697403064},
+ {4.230590107040037, 4.237190091606401},
+ {191.15690296946235, 66.32113196255075},
+ {4.237190091606401, 4.230590107040037},
+ {102, 187, 106}},
+ {{191.15690296946235, 66.32113196255075},
+ {169.65368347112212, 24.528649968701657},
+ {4.237190091606401, 4.2437900761727665},
+ {191.3861699210563, 66.2041239519667},
+ {4.2437900761727665, 4.237190091606401},
+ {171, 71, 188}},
+ {{191.38616992105636, 66.20412395196666},
+ {170.15924649258585, 24.27063230433673},
+ {4.243790076172768, 4.250390060739132},
+ {191.616204124715, 66.08863163715256},
+ {4.250390060739132, 4.243790076172768},
+ {38, 198, 218}},
+ {{191.616204124715, 66.08863163715256},
+ {170.66650140321772, 24.01595694346463},
+ {4.250390060739132, 4.256990045305496},
+ {191.84699556023176, 65.97466004891186},
+ {4.256990045305496, 4.250390060739132},
+ {255, 110, 64}},
+ {{191.84699556023176, 65.97466004891186},
+ {171.1754261071777, 23.764634979651802},
+ {4.256990045305496, 4.263590029871862},
+ {192.07853417441524, 65.86221415180566},
+ {4.263590029871862, 4.256990045305496},
+ {212, 225, 87}},
+ {{192.07853417441524, 65.86221415180566},
+ {171.68599843588999, 23.516677360391967},
+ {4.263590029871862, 4.270190014438228},
+ {192.31080988152712, 65.75129884393658},
+ {4.270190014438228, 4.263590029871862},
+ {189, 189, 189}},
+ {{192.31080988152712, 65.75129884393658},
+ {172.1981961490085, 23.272094886629375},
+ {4.270190014438228, 4.276789999004592},
+ {192.54381256372162, 65.64191895673532},
+ {4.276789999004592, 4.270190014438228},
+ {92, 107, 192}},
+ {{192.54381256372162, 65.64191895673532},
+ {172.7119969353861, 23.03089821228815},
+ {4.276789999004592, 4.283389983570958},
+ {192.7775320714863, 65.53407925475014},
+ {4.283389983570958, 4.276789999004592},
+ {79, 195, 247}},
+ {{192.7775320714863, 65.53407925475014},
+ {173.2273784140467, 22.793097843808},
+ {4.283389983570958, 4.2899899681373235},
+ {193.01195822408394, 65.42778443543946},
+ {4.2899899681373235, 4.283389983570958},
+ {255, 167, 38}},
+ {{193.01195822408394, 65.42778443543946},
+ {173.74431813515946, 22.558704139687023},
+ {4.2899899681373235, 4.2965899527036875},
+ {193.24708080999608, 65.3230391289672},
+ {4.2965899527036875, 4.2899899681373235},
+ {66, 165, 245}},
+ {{193.24708080999608, 65.3230391289672},
+ {174.262793581017, 22.327727310030212},
+ {4.2965899527036875, 4.3031899372700515},
+ {193.48288958736805, 65.21984789800092},
+ {4.3031899372700515, 4.2965899527036875},
+ {239, 83, 80}},
+ {{193.48288958736805, 65.21984789800092},
+ {174.7827821670167, 22.1001774161046},
+ {4.3031899372700515, 4.309789921836417},
+ {193.71937428445483, 65.11821523751334},
+ {4.309789921836417, 4.3031899372700515},
+ {255, 202, 40}},
+ {{193.7193742844549, 65.11821523751331},
+ {175.30426124264415, 21.876064369901144},
+ {4.309789921836419, 4.316389906402783},
+ {193.95652460006858, 65.01814557458637},
+ {4.316389906402783, 4.309789921836419},
+ {102, 187, 106}},
+ {{193.95652460006858, 65.01814557458637},
+ {175.82720809245893, 21.65539793370327},
+ {4.316389906402783, 4.322989890969147},
+ {194.1943302040273, 64.91964326821835},
+ {4.322989890969147, 4.316389906402783},
+ {171, 71, 188}},
+ {{194.1943302040273, 64.91964326821835},
+ {176.35159993708584, 21.438187719660974},
+ {4.322989890969147, 4.329589875535513},
+ {194.43278073760504, 64.82271260913404},
+ {4.329589875535513, 4.322989890969147},
+ {38, 198, 218}},
+ {{194.43278073760504, 64.82271260913404},
+ {176.87741393420595, 21.224443189372508},
+ {4.329589875535513, 4.336189860101879},
+ {194.67186581398275, 64.72735781959793},
+ {4.336189860101879, 4.329589875535513},
+ {255, 110, 64}},
+ {{194.67186581398275, 64.72735781959793},
+ {177.4046271795517, 21.01417365347234},
+ {4.336189860101879, 4.342789844668243},
+ {194.911575018701, 64.63358305323013},
+ {4.342789844668243, 4.336189860101879},
+ {212, 225, 87}},
+ {{194.911575018701, 64.63358305323013},
+ {177.93321670790476, 20.807388271225435},
+ {4.342789844668243, 4.3493898292346085},
+ {195.15189791011366, 64.54139239482552},
+ {4.3493898292346085, 4.342789844668243},
+ {189, 189, 189}},
+ {{195.15189791011366, 64.54139239482552},
+ {178.46315949409683, 20.604096050128078},
+ {4.3493898292346085, 4.355989813800974},
+ {195.39282401984252, 64.45078986017583},
+ {4.355989813800974, 4.3493898292346085},
+ {92, 107, 192}},
+ {{195.39282401984252, 64.45078986017583},
+ {178.9944324540117, 20.40430584551595},
+ {4.355989813800974, 4.362589798367338},
+ {195.6343428532333, 64.36177939589473},
+ {4.362589798367338, 4.355989813800974},
+ {79, 195, 247}},
+ {{195.6343428532333, 64.36177939589473},
+ {179.52701244559137, 20.20802636017811},
+ {4.362589798367338, 4.369189782933702},
+ {195.87644388981312, 64.27436487924578},
+ {4.369189782933702, 4.362589798367338},
+ {255, 167, 38}},
+ {{195.87644388981317, 64.27436487924575},
+ {180.0608762698444, 20.01526614397781},
+ {4.369189782933704, 4.37578976750007},
+ {196.1191165837485, 64.18855011797365},
+ {4.37578976750007, 4.369189782933704},
+ {66, 165, 245}},
+ {{196.1191165837485, 64.18855011797365},
+ {180.59600067185568, 19.826033593480375},
+ {4.37578976750007, 4.382389752066434},
+ {196.36235036430452, 64.10433885013842},
+ {4.382389752066434, 4.37578976750007},
+ {239, 83, 80}},
+ {{196.36235036430452, 64.10433885013842},
+ {181.1323623417997, 19.640336951587273},
+ {4.382389752066434, 4.388989736632798},
+ {196.60613463630577, 64.02173474395235},
+ {4.388989736632798, 4.382389752066434},
+ {255, 202, 40}},
+ {{196.60613463630577, 64.02173474395235},
+ {181.66993791595633, 19.458184307176978},
+ {4.388989736632798, 4.395589721199164},
+ {196.8504587805977, 63.94074139762042},
+ {4.395589721199164, 4.388989736632798},
+ {102, 187, 106}},
+ {{196.8504587805977, 63.94074139762042},
+ {182.20870397772828, 19.279583594752737},
+ {4.395589721199164, 4.4021897057655295},
+ {197.0953121545089, 63.86136233918352},
+ {4.4021897057655295, 4.395589721199164},
+ {171, 71, 188}},
+ {{197.0953121545089, 63.86136233918352},
+ {182.74863705866062, 19.104542594096998},
+ {4.4021897057655295, 4.4087896903318935},
+ {197.34068409231492, 63.783601026364714},
+ {4.4087896903318935, 4.4021897057655295},
+ {38, 198, 218}},
+ {{197.34068409231492, 63.783601026364714},
+ {183.28971363946366, 18.933068929932446},
+ {4.4087896903318935, 4.415389674898259},
+ {197.5865639057031, 63.70746084641862},
+ {4.415389674898259, 4.4087896903318935},
+ {255, 110, 64}},
+ {{197.5865639057031, 63.70746084641862},
+ {183.83191015103756, 18.76517007158978},
+ {4.415389674898259, 4.421989659464625},
+ {197.83294088423762, 63.632945115983944},
+ {4.421989659464625, 4.415389674898259},
+ {212, 225, 87}},
+ {{197.83294088423762, 63.632945115983944},
+ {184.37520297549833, 18.600853332682547},
+ {4.421989659464625, 4.428589644030989},
+ {198.07980429582642, 63.56005708093896},
+ {4.428589644030989, 4.421989659464625},
+ {189, 189, 189}},
+ {{198.07980429582642, 63.56005708093896},
+ {184.91956844720698, 18.440125870788478},
+ {4.428589644030989, 4.435189628597355},
+ {198.32714338718876, 63.48879991626006},
+ {4.435189628597355, 4.428589644030989},
+ {92, 107, 192}},
+ {{198.32714338718876, 63.48879991626006},
+ {185.46498285380085, 18.28299468713756},
+ {4.435189628597355, 4.441789613163721},
+ {198.57494738432322, 63.419176725883574},
+ {4.441789613163721, 4.435189628597355},
+ {79, 195, 247}},
+ {{198.57494738432322, 63.419176725883574},
+ {186.01142243722558, 18.129466626307362},
+ {4.441789613163721, 4.448389597730085},
+ {198.8232054929773, 63.3511905425705},
+ {4.448389597730085, 4.441789613163721},
+ {255, 167, 38}},
+ {{198.8232054929773, 63.3511905425705},
+ {186.5588633947705, 17.97954837592468},
+ {4.448389597730085, 4.461589566862816},
+ {199.3210407694013, 63.220140971512244},
+ {4.461589566862816, 4.448389597730085},
+ {66, 165, 245}},
+ {{199.3210407694013, 63.220140971512244},
+ {187.6566540043208, 17.690567270514165},
+ {4.461589566862816, 4.46818955142918},
+ {199.57059625164655, 63.15708329223899},
+ {4.46818955142918, 4.461589566862816},
+ {239, 83, 80}},
+ {{199.57059625164655, 63.15708329223899},
+ {188.20695583696417, 17.551517003398786},
+ {4.46818955142918, 4.474789535995544},
+ {199.8205624753071, 63.095674036724255},
+ {4.474789535995544, 4.46818955142918},
+ {255, 202, 40}},
+ {{199.82056247530716, 63.09567403672424},
+ {188.75816340708758, 17.416101722007298},
+ {4.474789535995546, 4.481389520561912},
+ {200.0709285519448, 63.03591587993297},
+ {4.481389520561912, 4.474789535995546},
+ {102, 187, 106}},
+ {{200.0709285519448, 63.03591587993297},
+ {189.31025270428856, 17.284327324980396},
+ {4.481389520561912, 4.487989505128276},
+ {200.32168357570373, 62.97781142490888},
+ {4.487989505128276, 4.481389520561912},
+ {171, 71, 188}},
+ {{200.32168357570373, 62.97781142490888},
+ {189.86319967975695, 17.156199552363162},
+ {4.487989505128276, 4.49458948969464},
+ {200.57281662378588, 62.921363202660984},
+ {4.49458948969464, 4.487989505128276},
+ {38, 198, 218}},
+ {{200.57281662378588, 62.921363202660984},
+ {190.41698024732275, 17.031723985355},
+ {4.49458948969464, 4.501189474261006},
+ {200.82431675692666, 62.86657367205342},
+ {4.501189474261006, 4.49458948969464},
+ {255, 110, 64}},
+ {{200.82431675692672, 62.8665736720534},
+ {190.9715702845051, 16.910906046066472},
+ {4.5011894742610075, 4.5077894588273715},
+ {201.07617301987116, 62.8134452196983},
+ {4.5077894588273715, 4.5011894742610075},
+ {212, 225, 87}},
+ {{201.07617301987116, 62.8134452196983},
+ {191.52694563356206, 16.79375099728344},
+ {4.5077894588273715, 4.5143894433937355},
+ {201.32837444185168, 62.76198015985183},
+ {4.5143894433937355, 4.5077894588273715},
+ {189, 189, 189}},
+ {{201.32837444185168, 62.76198015985183},
+ {192.0830821025447, 16.68026394223736},
+ {4.5143894433937355, 4.520989427960101},
+ {201.5809100370656, 62.71218073431335},
+ {4.520989427960101, 4.5143894433937355},
+ {92, 107, 192}},
+ {{201.5809100370656, 62.71218073431335},
+ {192.6399554663498, 16.570449824383275},
+ {4.520989427960101, 4.527589412526467},
+ {201.83376880515377, 62.664049112327824},
+ {4.527589412526467, 4.520989427960101},
+ {79, 195, 247}},
+ {{201.83376880515377, 62.664049112327824},
+ {193.19754146777498, 16.464313427184436},
+ {4.527589412526467, 4.534189397092831},
+ {202.08693973167965, 62.61758739049132},
+ {4.534189397092831, 4.527589412526467},
+ {255, 167, 38}},
+ {{202.08693973167965, 62.61758739049132},
+ {193.75581581857563, 16.36185937390394},
+ {4.534189397092831, 4.540789381659197},
+ {202.34041178860943, 62.5727975926596},
+ {4.540789381659197, 4.534189397092831},
+ {66, 165, 245}},
+ {{202.34041178860943, 62.5727975926596},
+ {194.31475420052337, 16.263092127403226},
+ {4.540789381659197, 4.547389366225563},
+ {202.59417393479197, 62.529681669860054},
+ {4.547389366225563, 4.540789381659197},
+ {239, 83, 80}},
+ {{202.59417393479197, 62.529681669860054},
+ {194.87433226646434, 16.16801598994782},
+ {4.547389366225563, 4.553989350791927},
+ {202.84821511643992, 62.4882415002067},
+ {4.553989350791927, 4.547389366225563},
+ {255, 202, 40}},
+ {{202.84821511643992, 62.4882415002067},
+ {195.43452564138033, 16.076635103019896},
+ {4.553989350791927, 4.560589335358291},
+ {203.10252426761141, 62.44847888881831},
+ {4.560589335358291, 4.553989350791927},
+ {102, 187, 106}},
+ {{203.10252426761141, 62.44847888881831},
+ {195.99530992345078, 15.988953447137803},
+ {4.560589335358291, 4.5671893199246565},
+ {203.3570903106919, 62.41039556773984},
+ {4.5671893199246565, 4.560589335358291},
+ {171, 71, 188}},
+ {{203.35709031069194, 62.41039556773983},
+ {196.5566606851156, 15.904974841682716},
+ {4.567189319924658, 4.573789304491022},
+ {203.6119021568766, 62.373993195867},
+ {4.573789304491022, 4.567189319924658},
+ {38, 198, 218}},
+ {{203.6119021568766, 62.373993195867},
+ {197.1185534741381, 15.824702944732365},
+ {4.573789304491022, 4.580389289057386},
+ {203.8669487066536, 62.33927335887393},
+ {4.580389289057386, 4.573789304491022},
+ {255, 110, 64}},
+ {{203.8669487066536, 62.33927335887393},
+ {197.68096381467205, 15.74814125290149},
+ {4.580389289057386, 4.586989273623752},
+ {204.12221885028765, 62.30623756914416},
+ {4.586989273623752, 4.580389289057386},
+ {212, 225, 87}},
+ {{204.12221885028765, 62.30623756914416},
+ {198.24386720832663, 15.67529310118968},
+ {4.586989273623752, 4.593589258190118},
+ {204.3777014683036, 62.274887265704734},
+ {4.593589258190118, 4.586989273623752},
+ {189, 189, 189}},
+ {{204.3777014683036, 62.274887265704734},
+ {198.80723913523357, 15.606161662836087},
+ {4.593589258190118, 4.600189242756482},
+ {204.63338543197096, 62.245223814163545},
+ {4.600189242756482, 4.593589258190118},
+ {92, 107, 192}},
+ {{204.63338543197096, 62.245223814163545},
+ {199.37105505511542, 15.540749949181148},
+ {4.600189242756482, 4.606789227322848},
+ {204.88925960378893, 62.21724850664979},
+ {4.606789227322848, 4.600189242756482},
+ {79, 195, 247}},
+ {{204.88925960378893, 62.21724850664979},
+ {199.93529040835506, 15.479060809535426},
+ {4.606789227322848, 4.6133892118892135},
+ {205.1453128379711, 62.190962561757736},
+ {4.6133892118892135, 4.606789227322848},
+ {255, 167, 38}},
+ {{205.1453128379711, 62.190962561757736},
+ {200.49992061706448, 15.42109693105553},
+ {4.6133892118892135, 4.6199891964555775},
+ {205.4015339809312, 62.166367124493654},
+ {4.6199891964555775, 4.6133892118892135},
+ {66, 165, 245}},
+ {{205.4015339809312, 62.166367124493654},
+ {201.06492108615595, 15.366860838627034},
+ {4.6199891964555775, 4.626589181021943},
+ {205.65791187176904, 62.14346326622588},
+ {4.626589181021943, 4.6199891964555775},
+ {239, 83, 80}},
+ {{205.65791187176904, 62.14346326622588},
+ {201.6302672044138, 15.316354894754497},
+ {4.626589181021943, 4.633189165588309},
+ {205.91443534275646, 62.12225198463818},
+ {4.633189165588309, 4.626589181021943},
+ {255, 202, 40}},
+ {{205.91443534275646, 62.12225198463818},
+ {202.19593434556555, 15.269581299458551},
+ {4.633189165588309, 4.639789150154673},
+ {206.17109321982377, 62.10273420368633},
+ {4.639789150154673, 4.633189165588309},
+ {102, 187, 106}},
+ {{206.17109321982377, 62.10273420368633},
+ {202.761897869355, 15.226542090180118},
+ {4.639789150154673, 4.646389134721039},
+ {206.4278743230469, 62.084910773557795},
+ {4.646389134721039, 4.639789150154673},
+ {171, 71, 188}},
+ {{206.4278743230469, 62.084910773557795},
+ {203.3281331226162, 15.187239141691535},
+ {4.646389134721039, 4.652989119287405},
+ {206.68476746713378, 62.06878247063473},
+ {4.652989119287405, 4.646389134721039},
+ {38, 198, 218}},
+ {{206.68476746713378, 62.06878247063473},
+ {203.89461544034626, 15.151674166015042},
+ {4.652989119287405, 4.659589103853769},
+ {206.94176146191197, 62.054349997460186},
+ {4.659589103853769, 4.652989119287405},
+ {255, 110, 64}},
+ {{206.94176146191197, 62.054349997460186},
+ {204.46132014678022, 15.119848712348102},
+ {4.659589103853769, 4.666189088420133},
+ {207.19884511281612, 62.041613982707474},
+ {4.666189088420133, 4.659589103853769},
+ {212, 225, 87}},
+ {{207.19884511281617, 62.041613982707474},
+ {205.02822255646643, 15.091764166995972},
+ {4.6661890884201345, 4.6727890729865},
+ {207.45600722137553, 62.03057498115278},
+ {4.6727890729865, 4.6661890884201345},
+ {189, 189, 189}},
+ {{207.45600722137553, 62.03057498115278},
+ {205.5952979753409, 15.067421753311265},
+ {4.6727890729865, 4.679389057552864},
+ {207.71323658570157, 62.02123347365103},
+ {4.679389057552864, 4.6727890729865},
+ {92, 107, 192}},
+ {{207.71323658570157, 62.02123347365103},
+ {206.16252170180348, 15.046822531640728},
+ {4.679389057552864, 4.685989042119228},
+ {207.97052200097633, 62.0135898671149},
+ {4.685989042119228, 4.679389057552864},
+ {79, 195, 247}},
+ {{207.97052200097633, 62.0135898671149},
+ {206.72986902779397, 15.029967399279002},
+ {4.685989042119228, 4.692589026685594},
+ {208.2278522599403, 62.00764449449712},
+ {4.692589026685594, 4.685989042119228},
+ {255, 167, 38}},
+ {{208.2278522599403, 62.00764449449712},
+ {207.29731523986834, 15.016857090429554},
+ {4.692589026685594, 4.69918901125196},
+ {208.4852161533804, 62.003397614775984},
+ {4.69918901125196, 4.692589026685594},
+ {66, 165, 245}},
+ {{208.4852161533804, 62.003397614775984},
+ {207.86483562027476, 15.00749217617269},
+ {4.69918901125196, 4.705788995818324},
+ {208.74260247061855, 62.00084941294403},
+ {4.705788995818324, 4.69918901125196},
+ {239, 83, 80}},
+ {{208.74260247061855, 62.00084941294403},
+ {208.43240544803064, 15.001873064440673},
+ {4.705788995818324, 4.71238898038469},
+ {209, 62},
+ {4.71238898038469, 4.705788995818324},
+ {255, 202, 40}},
+};
+void draw(SkCanvas* canvas) {
+ SkRect oval1 = {209 - 86, 101 - 86, 209 + 86, 101 + 86};
+ SkRect oval2 = {209 - 39, 101 - 39, 209 + 39, 101 + 39};
+ for (const auto& wedge : wedges) {
+ SkPath path;
+ path.moveTo(SkDoubleToScalar(wedge.fMove[0]), SkDoubleToScalar(wedge.fMove[1]));
+ path.lineTo(SkDoubleToScalar(wedge.fLine1[0]), SkDoubleToScalar(wedge.fLine1[1]));
+ SkASSERT(wedge.fArc1Angles[0] == wedge.fArc2Angles[1]);
+ SkASSERT(wedge.fArc1Angles[1] == wedge.fArc2Angles[0]);
+ SkScalar start = SkDoubleToScalar(wedge.fArc1Angles[0] * 180.f / SK_ScalarPI);
+ SkScalar end = SkDoubleToScalar(wedge.fArc1Angles[1] * 180.f / SK_ScalarPI);
+ if (end < start) {
+ end += 360;
+ }
+ path.arcTo(oval1, start, end - start, false);
+ path.lineTo(SkDoubleToScalar(wedge.fLine2[0]), SkDoubleToScalar(wedge.fLine2[1]));
+ path.arcTo(oval2, end, start - end, false);
+ path.close();
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setARGB(255, wedge.fRGB[0], wedge.fRGB[1], wedge.fRGB[2]);
+ canvas->drawPath(path, paint);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/bug6495.cpp b/docs/examples/bug6495.cpp
new file mode 100644
index 0000000..010ec7e
--- /dev/null
+++ b/docs/examples/bug6495.cpp
@@ -0,0 +1,35 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(bug6495, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(10);
+
+ SkRect r = SkRect::MakeXYWH(20, 20, 100, 100);
+
+ canvas->rotate(90);
+ canvas->scale(1.0, -1.0);
+ canvas->drawOval(r, p);
+
+ p.setColor(SK_ColorGREEN);
+
+ canvas->save();
+ canvas->scale(1.0, 0.4999);
+ canvas->drawOval(r, p);
+ canvas->restore();
+
+ canvas->save();
+ canvas->scale(1.0, 0.5000);
+ canvas->drawOval(r, p);
+ canvas->restore();
+
+ canvas->save();
+ canvas->scale(1.0, 0.5001);
+ canvas->drawOval(r, p);
+ canvas->restore();
+}
+} // END FIDDLE
diff --git a/docs/examples/bug7573.cpp b/docs/examples/bug7573.cpp
new file mode 100644
index 0000000..8a829b8
--- /dev/null
+++ b/docs/examples/bug7573.cpp
@@ -0,0 +1,18 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(bug7573, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setAntiAlias(true);
+ canvas->scale(0.196f * 2, 0.196f * 2);
+ SkPath path;
+ path.moveTo(SkBits2Float(0x40a1a3f7), SkBits2Float(0x41b80159)); // 5.05127f, 23.0007f
+ path.lineTo(SkBits2Float(0x42f41a3f), SkBits2Float(0x41d00159)); // 122.051f, 26.0007f
+ path.lineTo(SkBits2Float(0x42f3e5c1), SkBits2Float(0x41effea7)); // 121.949f, 29.9993f
+ path.lineTo(SkBits2Float(0x409e5c09), SkBits2Float(0x41d7fea7)); // 4.94873f, 26.9993f
+ path.lineTo(SkBits2Float(0x40a1a3f7), SkBits2Float(0x41b80159)); // 5.05127f, 23.0007f
+ path.close();
+ canvas->drawPath(path, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/bug767834.cpp b/docs/examples/bug767834.cpp
new file mode 100644
index 0000000..677cf84
--- /dev/null
+++ b/docs/examples/bug767834.cpp
@@ -0,0 +1,1253 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(bug767834, 350, 256, false, 0) {
+struct PieWedge {
+ double fMove[2];
+ double fLine1[2];
+ double fArc1Angles[2];
+ double fLine2[2];
+ double fArc2Angles[2];
+ unsigned char fRGB[3];
+} wedges[] = {
+
+ {{209, 62},
+ {208.99999999999997, 15},
+ {4.71238898038469, 4.864188625411087},
+ {214.8974757323885, 62.4484788888183},
+ {4.864188625411087, 4.71238898038469},
+ {66, 165, 245}},
+
+ {
+ {214.8974757323885, 62.4484788888183},
+ {222.00469007654902, 15.988953447137789},
+ {4.864188625411087, 5.939986109728601},
+ {245.72563512075425, 87.87644388981317},
+ {5.939986109728601, 4.864188625411087},
+ {239, 83, 80},
+ },
+
+ {
+ {245.72563512075425, 87.87644388981317},
+ {289.9847338560222, 72.06087626984443},
+ {5.939986109728601, 0.6071985801055906},
+ {241.02873602896423, 123.25219244000306},
+ {0.6071985801055906, 5.939986109728601},
+ {255, 202, 40},
+ },
+
+ {
+ {241.02873602896423, 123.25219244000306},
+ {279.62746919207495, 150.06893717539134},
+ {0.6071985801055906, 1.2143971602111803},
+ {222.6071759801575, 137.54921013982414},
+ {1.2143971602111803, 0.6071985801055906},
+ {102, 187, 106},
+ },
+
+ {
+ {222.6071759801575, 137.54921013982414},
+ {239.00556754598836, 181.59569415448402},
+ {1.2143971602111803, 1.5905962804939922},
+ {208.2278522599403, 139.99235550550287},
+ {1.5905962804939922, 1.2143971602111803},
+ {171, 71, 188},
+ },
+
+ {
+ {208.2278522599403, 139.99235550550287},
+ {207.29731523986837, 186.98314290957046},
+ {1.5905962804939922, 1.8479956785822313},
+ {198.32714338718876, 138.51120008373994},
+ {1.8479956785822313, 1.5905962804939922},
+ {38, 198, 218},
+ },
+
+ {
+ {198.32714338718876, 138.51120008373994},
+ {185.46498285380088, 183.71700531286245},
+ {1.8479956785822313, 2.0657951692722794},
+ {190.473805325209, 135.3188011281243},
+ {2.0657951692722794, 1.8479956785822313},
+ {255, 110, 64},
+ },
+
+ {
+ {190.47380532520896, 135.31880112812428},
+ {168.1473655889223, 176.6773563338125},
+ {2.065795169272281, 2.296794629095059},
+ {183.10858870915067, 130.16564453887622},
+ {2.296794629095059, 2.065795169272281},
+ {212, 225, 87},
+ },
+
+ {
+ {183.10858870915067, 130.16564453887622},
+ {151.90611869197326, 165.31398539341933},
+ {2.296794629095059, 2.461794243254186},
+ {178.66972101612106, 125.51681416416235},
+ {2.461794243254186, 2.296794629095059},
+ {189, 189, 189},
+ },
+
+ {
+ {178.66972101612106, 125.51681416416235},
+ {142.1178463432413, 155.06271841328106},
+ {2.461794243254186, 2.5937939345814893},
+ {175.7067515538738, 121.31156340374902},
+ {2.5937939345814893, 2.461794243254186},
+ {92, 107, 192},
+ },
+
+ {
+ {175.70675155387386, 121.31156340374908},
+ {135.58411881110644, 145.78960135185693},
+ {2.5937939345814875, 2.719193641342425},
+ {173.4277844354395, 116.98804177591612},
+ {2.719193641342425, 2.5937939345814875},
+ {79, 195, 247},
+ },
+
+ {
+ {173.4277844354395, 116.98804177591612},
+ {130.55870413968708, 136.25568186484068},
+ {2.719193641342425, 2.831393378970633},
+ {171.86136233918353, 112.90468784549111},
+ {2.831393378970633, 2.719193641342425},
+ {255, 167, 38},
+ },
+
+ {
+ {171.86136233918353, 112.90468784549111},
+ {127.104542594097, 127.25136294133937},
+ {2.831393378970633, 2.9435931165988407},
+ {170.76198015985182, 108.67162555814826},
+ {2.9435931165988407, 2.831393378970633},
+ {66, 165, 245},
+ },
+
+ {
+ {170.76198015985182, 108.67162555814826},
+ {124.68026394223733, 117.91691789745515},
+ {2.9435931165988407, 2.99639299312976},
+ {170.41039556773984, 106.64290968930811},
+ {2.99639299312976, 2.9435931165988407},
+ {239, 83, 80},
+ },
+
+ {
+ {170.41039556773984, 106.64290968930811},
+ {123.90497484168273, 113.44333931488454},
+ {2.99639299312976, 3.095392761625238},
+ {170.04161398270747, 102.80115488718383},
+ {3.095392761625238, 2.99639299312976},
+ {255, 202, 40},
+ },
+
+ {
+ {170.04161398270747, 102.80115488718383},
+ {123.09176416699597, 104.97177744353357},
+ {3.095392761625238, 3.194392530120716},
+ {170.05434999746018, 98.9417614619119},
+ {3.194392530120716, 3.095392761625238},
+ {102, 187, 106},
+ },
+
+ {
+ {170.05434999746018, 98.94176146191197},
+ {123.1198487123481, 96.46132014678024},
+ {3.194392530120714, 3.2735923449170947},
+ {170.33927335887392, 95.86694870665369},
+ {3.2735923449170947, 3.194392530120714},
+ {171, 71, 188},
+ },
+
+ {
+ {170.33927335887392, 95.86694870665369},
+ {123.74814125290146, 89.68096381467222},
+ {3.2735923449170947, 3.352792159713477},
+ {170.86657367205342, 92.82431675692668},
+ {3.352792159713477, 3.2735923449170947},
+ {38, 198, 218},
+ },
+
+ {
+ {170.86657367205342, 92.82431675692668},
+ {124.9109060460665, 82.97157028450496},
+ {3.352792159713477, 3.412192020810762},
+ {171.41917672588357, 90.57494738432324},
+ {3.412192020810762, 3.352792159713477},
+ {255, 110, 64},
+ },
+
+ {
+ {171.41917672588357, 90.57494738432324},
+ {126.12946662630736, 78.0114224372256},
+ {3.412192020810762, 3.471591881908047},
+ {172.1043388501384, 88.36235036430459},
+ {3.471591881908047, 3.412192020810762},
+ {212, 225, 87},
+ },
+
+ {
+ {172.1043388501384, 88.36235036430453},
+ {127.64033695158726, 73.13236234179972},
+ {3.471591881908049, 3.5375917275716997},
+ {173.01814557458636, 85.9565246000686},
+ {3.5375917275716997, 3.471591881908049},
+ {189, 189, 189},
+ },
+
+ {
+ {173.01814557458636, 85.9565246000686},
+ {129.65539793370326, 67.82720809245897},
+ {3.5375917275716997, 3.5441917121380655},
+ {173.11821523751334, 85.71937428445484},
+ {3.5441917121380655, 3.5375917275716997},
+ {92, 107, 192},
+ },
+
+ {
+ {173.11821523751334, 85.71937428445484},
+ {129.8760643699012, 67.30426124264403},
+ {3.5441917121380655, 3.5969915886689847},
+ {173.97466004891183, 83.84699556023183},
+ {3.5969915886689847, 3.5441917121380655},
+ {79, 195, 247},
+ },
+
+ {
+ {173.97466004891183, 83.84699556023183},
+ {131.7646349796517, 63.17542610717788},
+ {3.5969915886689847, 3.6497914651999075},
+ {174.9287267647916, 82.02242533589258},
+ {3.6497914651999075, 3.5969915886689847},
+ {255, 167, 38},
+ },
+
+ {
+ {174.9287267647916, 82.02242533589258},
+ {133.86847440441224, 59.15201484325031},
+ {3.6497914651999075, 3.689391372598097},
+ {175.7067515538738, 80.688436596251},
+ {3.689391372598097, 3.6497914651999075},
+ {66, 165, 245},
+ },
+
+ {
+ {175.70675155387386, 80.68843659625094},
+ {135.5841188111064, 56.210398648143084},
+ {3.6893913725980987, 3.728991279996288},
+ {176.53697841699477, 79.38629532677618},
+ {3.728991279996288, 3.6893913725980987},
+ {239, 83, 80},
+ },
+
+ {
+ {176.53697841699477, 79.38629532677618},
+ {137.41487548362952, 53.33901020776284},
+ {3.728991279996288, 3.7619912028281135},
+ {177.26777398454274, 78.32698008416307},
+ {3.7619912028281135, 3.728991279996288},
+ {255, 202, 40},
+ },
+
+ {
+ {177.26777398454274, 78.32698008416307},
+ {139.0263734018122, 51.003084288154476},
+ {3.7619912028281135, 3.788391141093573},
+ {177.87732813607064, 77.49724918120904},
+ {3.788391141093573, 3.7619912028281135},
+ {102, 187, 106},
+ },
+
+ {
+ {177.87732813607064, 77.49724918120904},
+ {140.37051845389936, 49.17342127138402},
+ {3.788391141093573, 3.8147910793590345},
+ {178.50857218374682, 76.68389772750939},
+ {3.8147910793590345, 3.788391141093573},
+ {171, 71, 188},
+ },
+
+ {
+ {178.50857218374682, 76.68389772750939},
+ {141.7624925077494, 47.379877040148926},
+ {3.8147910793590345, 3.83459103305813},
+ {178.99597513166773, 76.0849745795735},
+ {3.83459103305813, 3.8147910793590345},
+ {38, 198, 218},
+ },
+
+ {
+ {178.99597513166773, 76.0849745795735},
+ {142.83727849547242, 46.05917471393132},
+ {3.83459103305813, 3.8543909867572257},
+ {179.49514041820387, 75.49581875341823},
+ {3.8543909867572257, 3.83459103305813},
+ {255, 110, 64},
+ },
+
+ {
+ {179.49514041820387, 75.49581875341823},
+ {143.93800194783418, 44.76001058446072},
+ {3.8543909867572257, 3.8741909404563213},
+ {180.0058723579047, 74.91666121306773},
+ {3.8741909404563213, 3.8543909867572257},
+ {212, 225, 87},
+ },
+
+ {
+ {180.00587235790465, 74.91666121306778},
+ {145.0642313533282, 43.482893957021275},
+ {3.8741909404563195, 3.893990894155415},
+ {180.52797073089823, 74.34772900296463},
+ {3.893990894155415, 3.8741909404563195},
+ {189, 189, 189},
+ },
+
+ {
+ {180.52797073089823, 74.34772900296463},
+ {146.21552520146793, 42.22832549371687},
+ {3.893990894155415, 3.9137908478545107},
+ {181.06123086138257, 73.78924515896263},
+ {3.9137908478545107, 3.893990894155415},
+ {92, 107, 192},
+ },
+
+ {
+ {181.06123086138257, 73.78924515896263},
+ {147.39143215586927, 40.996797017199654},
+ {3.9137908478545107, 3.9335908015536063},
+ {181.60544369786365, 73.24142862089114},
+ {3.9335908015536063, 3.9137908478545107},
+ {79, 195, 247},
+ },
+
+ {
+ {181.60544369786365, 73.24142862089114},
+ {148.59149123118652, 39.78879131786252},
+ {3.9335908015536063, 3.953390755252702},
+ {182.16039589510896, 72.70449414672505},
+ {3.953390755252702, 3.9335908015536063},
+ {255, 167, 38},
+ },
+
+ {
+ {182.16039589510896, 72.70449414672505},
+ {149.81523197383004, 38.604781964573206},
+ {3.953390755252702, 3.9731907089517975},
+ {182.72586989778426, 72.1786522283943},
+ {3.9731907089517975, 3.953390755252702},
+ {66, 165, 245},
+ },
+
+ {
+ {182.72586989778426, 72.1786522283943},
+ {151.0621746463961, 37.44523311902331},
+ {3.9731907089517975, 3.9863906780845255},
+ {183.1085887091506, 71.83435546112383},
+ {3.9863906780845255, 3.9731907089517975},
+ {239, 83, 80},
+ },
+
+ {
+ {183.10858870915067, 71.83435546112379},
+ {151.90611869197326, 36.68601460658067},
+ {3.9863906780845273, 3.999590647217257},
+ {183.49581875341823, 71.49514041820387},
+ {3.999590647217257, 3.9863906780845273},
+ {255, 202, 40},
+ },
+
+ {
+ {183.49581875341823, 71.49514041820387},
+ {152.7600105844607, 35.938001947834195},
+ {3.999590647217257, 4.012790616349987},
+ {183.88749256091927, 71.161066203329},
+ {4.012790616349987, 3.999590647217257},
+ {102, 187, 106},
+ },
+
+ {
+ {183.8874925609193, 71.16106620332897},
+ {153.6237015445913, 35.20132547400746},
+ {4.012790616349989, 4.025990585482717},
+ {184.28354188771962, 70.83219102447296},
+ {4.025990585482717, 4.012790616349989},
+ {171, 71, 188},
+ },
+
+ {
+ {184.28354188771968, 70.83219102447292},
+ {154.49704108574082, 34.47611354114541},
+ {4.0259905854827185, 4.039190554615448},
+ {184.6838977275094, 70.50857218374685},
+ {4.039190554615448, 4.0259905854827185},
+ {38, 198, 218},
+ },
+
+ {
+ {184.6838977275094, 70.50857218374685},
+ {155.3798770401489, 33.76249250774944},
+ {4.039190554615448, 4.052390523748178},
+ {185.08849032362605, 70.19026606741508},
+ {4.052390523748178, 4.039190554615448},
+ {255, 110, 64},
+ },
+
+ {
+ {185.0884903236261, 70.19026606741504},
+ {156.2720555854319, 33.06058671276138},
+ {4.05239052374818, 4.065590492880908},
+ {185.49724918120899, 69.87732813607067},
+ {4.065590492880908, 4.05239052374818},
+ {212, 225, 87},
+ },
+
+ {
+ {185.49724918120899, 69.87732813607067},
+ {157.1734212713839, 32.37051845389945},
+ {4.065590492880908, 4.0787904620136395},
+ {185.91010307948213, 69.56981291497203},
+ {4.0787904620136395, 4.065590492880908},
+ {189, 189, 189},
+ },
+
+ {
+ {185.91010307948213, 69.56981291497203},
+ {158.08381704706312, 31.692407966348583},
+ {4.0787904620136395, 4.091990431146369},
+ {186.32698008416307, 69.26777398454276},
+ {4.091990431146369, 4.0787904620136395},
+ {92, 107, 192},
+ },
+
+ {
+ {186.32698008416307, 69.26777398454276},
+ {159.00308428815444, 31.026373401812222},
+ {4.091990431146369, 4.105190400279099},
+ {186.74780755999694, 68.97126397103578},
+ {4.105190400279099, 4.091990431146369},
+ {79, 195, 247},
+ },
+
+ {
+ {186.74780755999694, 68.97126397103578},
+ {159.93106282460863, 30.37253080792506},
+ {4.105190400279099, 4.118390369411829},
+ {187.17251218341195, 68.68033453736409},
+ {4.118390369411829, 4.105190400279099},
+ {255, 167, 38},
+ },
+
+ {
+ {187.172512183412, 68.68033453736405},
+ {160.86759096854956, 29.730994108033556},
+ {4.118390369411831, 4.131590338544559},
+ {187.60101995529507, 68.3950363740991},
+ {4.131590338544559, 4.118390369411831},
+ {66, 165, 245},
+ },
+
+ {
+ {187.60101995529507, 68.3950363740991},
+ {161.81250554244556, 29.101875081346734},
+ {4.131590338544559, 4.14479030767729},
+ {188.0332562138855, 68.11541919063848},
+ {4.14479030767729, 4.131590338544559},
+ {239, 83, 80},
+ },
+
+ {
+ {188.0332562138855, 68.11541919063848},
+ {162.76564190754235, 28.4852833434592},
+ {4.14479030767729, 4.151390292243654},
+ {188.25074901590185, 67.97775623009694},
+ {4.151390292243654, 4.14479030767729},
+ {255, 202, 40},
+ },
+
+ {
+ {188.25074901590185, 67.97775623009694},
+ {163.24524141968098, 28.181718866367618},
+ {4.151390292243654, 4.15799027681002},
+ {188.4691456477831, 67.84153170654506},
+ {4.15799027681002, 4.151390292243654},
+ {102, 187, 106},
+ },
+
+ {
+ {188.4691456477831, 67.84153170654506},
+ {163.72683399254737, 27.88132632725319},
+ {4.15799027681002, 4.164590261376386},
+ {188.688436596251, 67.70675155387381},
+ {4.164590261376386, 4.15799027681002},
+ {171, 71, 188},
+ },
+
+ {
+ {188.688436596251, 67.70675155387381},
+ {164.21039864814318, 27.584118811106364},
+ {4.164590261376386, 4.17119024594275},
+ {188.90861230907103, 67.57342164305794},
+ {4.17119024594275, 4.164590261376386},
+ {38, 198, 218},
+ },
+
+ {
+ {188.90861230907103, 67.57342164305794},
+ {164.6959143225669, 27.290109264179037},
+ {4.17119024594275, 4.177790230509116},
+ {189.129663195469, 67.44154778190001},
+ {4.177790230509116, 4.17119024594275},
+ {255, 110, 64},
+ },
+
+ {
+ {189.129663195469, 67.44154778190001},
+ {165.1833598669316, 26.999310493420538},
+ {4.177790230509116, 4.1843902150754815},
+ {189.35157962654816, 67.31113571477775},
+ {4.1843902150754815, 4.177790230509116},
+ {212, 225, 87},
+ },
+
+ {
+ {189.35157962654816, 67.31113571477775},
+ {165.6727140482857, 26.711735165920174},
+ {4.1843902150754815, 4.1909901996418455},
+ {189.57435193570907, 67.18219112239366},
+ {4.1909901996418455, 4.1843902150754815},
+ {189, 189, 189},
+ },
+
+ {
+ {189.57435193570907, 67.18219112239366},
+ {166.16395555053796, 26.427395808355243},
+ {4.1909901996418455, 4.1975901842082095},
+ {189.7979704190706, 67.05471962152747},
+ {4.1975901842082095, 4.1909901996418455},
+ {92, 107, 192},
+ },
+
+ {
+ {189.7979704190706, 67.05471962152747},
+ {166.65706297538645, 26.146304806445187},
+ {4.1975901842082095, 4.204190168774575},
+ {190.02242533589256, 66.9287267647916},
+ {4.204190168774575, 4.1975901842082095},
+ {79, 195, 247},
+ },
+
+ {
+ {190.02242533589262, 66.92872676479158},
+ {167.1520148432504, 25.868474404412183},
+ {4.204190168774577, 4.210790153340941},
+ {190.247706909, 66.80421804038936},
+ {4.210790153340941, 4.204190168774577},
+ {255, 167, 38},
+ },
+
+ {
+ {190.247706909, 66.80421804038936},
+ {167.64878959420508, 25.593916704448333},
+ {4.210790153340941, 4.217390137907305},
+ {190.47380532520896, 66.68119887187574},
+ {4.217390137907305, 4.210790153340941},
+ {66, 165, 245},
+ },
+
+ {
+ {190.47380532520896, 66.68119887187574},
+ {168.1473655889223, 25.322643666187517},
+ {4.217390137907305, 4.223990122473671},
+ {190.7007107357544, 66.55967461792113},
+ {4.223990122473671, 4.217390137907305},
+ {239, 83, 80},
+ },
+
+ {
+ {190.70071073575446, 66.5596746179211},
+ {168.6477211096124, 25.054667106185008},
+ {4.223990122473673, 4.230590107040037},
+ {190.9284132567187, 66.43965057207814},
+ {4.230590107040037, 4.223990122473673},
+ {255, 202, 40},
+ },
+
+ {
+ {190.9284132567187, 66.43965057207814},
+ {169.14983436096944, 24.789998697403064},
+ {4.230590107040037, 4.237190091606401},
+ {191.15690296946235, 66.32113196255075},
+ {4.237190091606401, 4.230590107040037},
+ {102, 187, 106},
+ },
+
+ {
+ {191.15690296946235, 66.32113196255075},
+ {169.65368347112212, 24.528649968701657},
+ {4.237190091606401, 4.2437900761727665},
+ {191.3861699210563, 66.2041239519667},
+ {4.2437900761727665, 4.237190091606401},
+ {171, 71, 188},
+ },
+
+ {
+ {191.38616992105636, 66.20412395196666},
+ {170.15924649258585, 24.27063230433673},
+ {4.243790076172768, 4.250390060739132},
+ {191.616204124715, 66.08863163715256},
+ {4.250390060739132, 4.243790076172768},
+ {38, 198, 218},
+ },
+
+ {
+ {191.616204124715, 66.08863163715256},
+ {170.66650140321772, 24.01595694346463},
+ {4.250390060739132, 4.256990045305496},
+ {191.84699556023176, 65.97466004891186},
+ {4.256990045305496, 4.250390060739132},
+ {255, 110, 64},
+ },
+
+ {
+ {191.84699556023176, 65.97466004891186},
+ {171.1754261071777, 23.764634979651802},
+ {4.256990045305496, 4.263590029871862},
+ {192.07853417441524, 65.86221415180566},
+ {4.263590029871862, 4.256990045305496},
+ {212, 225, 87},
+ },
+
+ {
+ {192.07853417441524, 65.86221415180566},
+ {171.68599843588999, 23.516677360391967},
+ {4.263590029871862, 4.270190014438228},
+ {192.31080988152712, 65.75129884393658},
+ {4.270190014438228, 4.263590029871862},
+ {189, 189, 189},
+ },
+
+ {
+ {192.31080988152712, 65.75129884393658},
+ {172.1981961490085, 23.272094886629375},
+ {4.270190014438228, 4.276789999004592},
+ {192.54381256372162, 65.64191895673532},
+ {4.276789999004592, 4.270190014438228},
+ {92, 107, 192},
+ },
+
+ {
+ {192.54381256372162, 65.64191895673532},
+ {172.7119969353861, 23.03089821228815},
+ {4.276789999004592, 4.283389983570958},
+ {192.7775320714863, 65.53407925475014},
+ {4.283389983570958, 4.276789999004592},
+ {79, 195, 247},
+ },
+
+ {
+ {192.7775320714863, 65.53407925475014},
+ {173.2273784140467, 22.793097843808},
+ {4.283389983570958, 4.2899899681373235},
+ {193.01195822408394, 65.42778443543946},
+ {4.2899899681373235, 4.283389983570958},
+ {255, 167, 38},
+ },
+
+ {
+ {193.01195822408394, 65.42778443543946},
+ {173.74431813515946, 22.558704139687023},
+ {4.2899899681373235, 4.2965899527036875},
+ {193.24708080999608, 65.3230391289672},
+ {4.2965899527036875, 4.2899899681373235},
+ {66, 165, 245},
+ },
+
+ {
+ {193.24708080999608, 65.3230391289672},
+ {174.262793581017, 22.327727310030212},
+ {4.2965899527036875, 4.3031899372700515},
+ {193.48288958736805, 65.21984789800092},
+ {4.3031899372700515, 4.2965899527036875},
+ {239, 83, 80},
+ },
+
+ {
+ {193.48288958736805, 65.21984789800092},
+ {174.7827821670167, 22.1001774161046},
+ {4.3031899372700515, 4.309789921836417},
+ {193.71937428445483, 65.11821523751334},
+ {4.309789921836417, 4.3031899372700515},
+ {255, 202, 40},
+ },
+
+ {
+ {193.7193742844549, 65.11821523751331},
+ {175.30426124264415, 21.876064369901144},
+ {4.309789921836419, 4.316389906402783},
+ {193.95652460006858, 65.01814557458637},
+ {4.316389906402783, 4.309789921836419},
+ {102, 187, 106},
+ },
+
+ {
+ {193.95652460006858, 65.01814557458637},
+ {175.82720809245893, 21.65539793370327},
+ {4.316389906402783, 4.322989890969147},
+ {194.1943302040273, 64.91964326821835},
+ {4.322989890969147, 4.316389906402783},
+ {171, 71, 188},
+ },
+
+ {
+ {194.1943302040273, 64.91964326821835},
+ {176.35159993708584, 21.438187719660974},
+ {4.322989890969147, 4.329589875535513},
+ {194.43278073760504, 64.82271260913404},
+ {4.329589875535513, 4.322989890969147},
+ {38, 198, 218},
+ },
+
+ {
+ {194.43278073760504, 64.82271260913404},
+ {176.87741393420595, 21.224443189372508},
+ {4.329589875535513, 4.336189860101879},
+ {194.67186581398275, 64.72735781959793},
+ {4.336189860101879, 4.329589875535513},
+ {255, 110, 64},
+ },
+
+ {
+ {194.67186581398275, 64.72735781959793},
+ {177.4046271795517, 21.01417365347234},
+ {4.336189860101879, 4.342789844668243},
+ {194.911575018701, 64.63358305323013},
+ {4.342789844668243, 4.336189860101879},
+ {212, 225, 87},
+ },
+
+ {
+ {194.911575018701, 64.63358305323013},
+ {177.93321670790476, 20.807388271225435},
+ {4.342789844668243, 4.3493898292346085},
+ {195.15189791011366, 64.54139239482552},
+ {4.3493898292346085, 4.342789844668243},
+ {189, 189, 189},
+ },
+
+ {
+ {195.15189791011366, 64.54139239482552},
+ {178.46315949409683, 20.604096050128078},
+ {4.3493898292346085, 4.355989813800974},
+ {195.39282401984252, 64.45078986017583},
+ {4.355989813800974, 4.3493898292346085},
+ {92, 107, 192},
+ },
+
+ {
+ {195.39282401984252, 64.45078986017583},
+ {178.9944324540117, 20.40430584551595},
+ {4.355989813800974, 4.362589798367338},
+ {195.6343428532333, 64.36177939589473},
+ {4.362589798367338, 4.355989813800974},
+ {79, 195, 247},
+ },
+
+ {
+ {195.6343428532333, 64.36177939589473},
+ {179.52701244559137, 20.20802636017811},
+ {4.362589798367338, 4.369189782933702},
+ {195.87644388981312, 64.27436487924578},
+ {4.369189782933702, 4.362589798367338},
+ {255, 167, 38},
+ },
+
+ {
+ {195.87644388981317, 64.27436487924575},
+ {180.0608762698444, 20.01526614397781},
+ {4.369189782933704, 4.37578976750007},
+ {196.1191165837485, 64.18855011797365},
+ {4.37578976750007, 4.369189782933704},
+ {66, 165, 245},
+ },
+
+ {
+ {196.1191165837485, 64.18855011797365},
+ {180.59600067185568, 19.826033593480375},
+ {4.37578976750007, 4.382389752066434},
+ {196.36235036430452, 64.10433885013842},
+ {4.382389752066434, 4.37578976750007},
+ {239, 83, 80},
+ },
+
+ {
+ {196.36235036430452, 64.10433885013842},
+ {181.1323623417997, 19.640336951587273},
+ {4.382389752066434, 4.388989736632798},
+ {196.60613463630577, 64.02173474395235},
+ {4.388989736632798, 4.382389752066434},
+ {255, 202, 40},
+ },
+
+ {
+ {196.60613463630577, 64.02173474395235},
+ {181.66993791595633, 19.458184307176978},
+ {4.388989736632798, 4.395589721199164},
+ {196.8504587805977, 63.94074139762042},
+ {4.395589721199164, 4.388989736632798},
+ {102, 187, 106},
+ },
+
+ {
+ {196.8504587805977, 63.94074139762042},
+ {182.20870397772828, 19.279583594752737},
+ {4.395589721199164, 4.4021897057655295},
+ {197.0953121545089, 63.86136233918352},
+ {4.4021897057655295, 4.395589721199164},
+ {171, 71, 188},
+ },
+
+ {
+ {197.0953121545089, 63.86136233918352},
+ {182.74863705866062, 19.104542594096998},
+ {4.4021897057655295, 4.4087896903318935},
+ {197.34068409231492, 63.783601026364714},
+ {4.4087896903318935, 4.4021897057655295},
+ {38, 198, 218},
+ },
+
+ {
+ {197.34068409231492, 63.783601026364714},
+ {183.28971363946366, 18.933068929932446},
+ {4.4087896903318935, 4.415389674898259},
+ {197.5865639057031, 63.70746084641862},
+ {4.415389674898259, 4.4087896903318935},
+ {255, 110, 64},
+ },
+
+ {
+ {197.5865639057031, 63.70746084641862},
+ {183.83191015103756, 18.76517007158978},
+ {4.415389674898259, 4.421989659464625},
+ {197.83294088423762, 63.632945115983944},
+ {4.421989659464625, 4.415389674898259},
+ {212, 225, 87},
+ },
+
+ {
+ {197.83294088423762, 63.632945115983944},
+ {184.37520297549833, 18.600853332682547},
+ {4.421989659464625, 4.428589644030989},
+ {198.07980429582642, 63.56005708093896},
+ {4.428589644030989, 4.421989659464625},
+ {189, 189, 189},
+ },
+
+ {
+ {198.07980429582642, 63.56005708093896},
+ {184.91956844720698, 18.440125870788478},
+ {4.428589644030989, 4.435189628597355},
+ {198.32714338718876, 63.48879991626006},
+ {4.435189628597355, 4.428589644030989},
+ {92, 107, 192},
+ },
+
+ {
+ {198.32714338718876, 63.48879991626006},
+ {185.46498285380085, 18.28299468713756},
+ {4.435189628597355, 4.441789613163721},
+ {198.57494738432322, 63.419176725883574},
+ {4.441789613163721, 4.435189628597355},
+ {79, 195, 247},
+ },
+
+ {
+ {198.57494738432322, 63.419176725883574},
+ {186.01142243722558, 18.129466626307362},
+ {4.441789613163721, 4.448389597730085},
+ {198.8232054929773, 63.3511905425705},
+ {4.448389597730085, 4.441789613163721},
+ {255, 167, 38},
+ },
+
+ {
+ {198.8232054929773, 63.3511905425705},
+ {186.5588633947705, 17.97954837592468},
+ {4.448389597730085, 4.461589566862816},
+ {199.3210407694013, 63.220140971512244},
+ {4.461589566862816, 4.448389597730085},
+ {66, 165, 245},
+ },
+
+ {
+ {199.3210407694013, 63.220140971512244},
+ {187.6566540043208, 17.690567270514165},
+ {4.461589566862816, 4.46818955142918},
+ {199.57059625164655, 63.15708329223899},
+ {4.46818955142918, 4.461589566862816},
+ {239, 83, 80},
+ },
+
+ {
+ {199.57059625164655, 63.15708329223899},
+ {188.20695583696417, 17.551517003398786},
+ {4.46818955142918, 4.474789535995544},
+ {199.8205624753071, 63.095674036724255},
+ {4.474789535995544, 4.46818955142918},
+ {255, 202, 40},
+ },
+
+ {
+ {199.82056247530716, 63.09567403672424},
+ {188.75816340708758, 17.416101722007298},
+ {4.474789535995546, 4.481389520561912},
+ {200.0709285519448, 63.03591587993297},
+ {4.481389520561912, 4.474789535995546},
+ {102, 187, 106},
+ },
+
+ {
+ {200.0709285519448, 63.03591587993297},
+ {189.31025270428856, 17.284327324980396},
+ {4.481389520561912, 4.487989505128276},
+ {200.32168357570373, 62.97781142490888},
+ {4.487989505128276, 4.481389520561912},
+ {171, 71, 188},
+ },
+
+ {
+ {200.32168357570373, 62.97781142490888},
+ {189.86319967975695, 17.156199552363162},
+ {4.487989505128276, 4.49458948969464},
+ {200.57281662378588, 62.921363202660984},
+ {4.49458948969464, 4.487989505128276},
+ {38, 198, 218},
+ },
+
+ {
+ {200.57281662378588, 62.921363202660984},
+ {190.41698024732275, 17.031723985355},
+ {4.49458948969464, 4.501189474261006},
+ {200.82431675692666, 62.86657367205342},
+ {4.501189474261006, 4.49458948969464},
+ {255, 110, 64},
+ },
+
+ {
+ {200.82431675692672, 62.8665736720534},
+ {190.9715702845051, 16.910906046066472},
+ {4.5011894742610075, 4.5077894588273715},
+ {201.07617301987116, 62.8134452196983},
+ {4.5077894588273715, 4.5011894742610075},
+ {212, 225, 87},
+ },
+
+ {
+ {201.07617301987116, 62.8134452196983},
+ {191.52694563356206, 16.79375099728344},
+ {4.5077894588273715, 4.5143894433937355},
+ {201.32837444185168, 62.76198015985183},
+ {4.5143894433937355, 4.5077894588273715},
+ {189, 189, 189},
+ },
+
+ {
+ {201.32837444185168, 62.76198015985183},
+ {192.0830821025447, 16.68026394223736},
+ {4.5143894433937355, 4.520989427960101},
+ {201.5809100370656, 62.71218073431335},
+ {4.520989427960101, 4.5143894433937355},
+ {92, 107, 192},
+ },
+
+ {
+ {201.5809100370656, 62.71218073431335},
+ {192.6399554663498, 16.570449824383275},
+ {4.520989427960101, 4.527589412526467},
+ {201.83376880515377, 62.664049112327824},
+ {4.527589412526467, 4.520989427960101},
+ {79, 195, 247},
+ },
+
+ {
+ {201.83376880515377, 62.664049112327824},
+ {193.19754146777498, 16.464313427184436},
+ {4.527589412526467, 4.534189397092831},
+ {202.08693973167965, 62.61758739049132},
+ {4.534189397092831, 4.527589412526467},
+ {255, 167, 38},
+ },
+
+ {
+ {202.08693973167965, 62.61758739049132},
+ {193.75581581857563, 16.36185937390394},
+ {4.534189397092831, 4.540789381659197},
+ {202.34041178860943, 62.5727975926596},
+ {4.540789381659197, 4.534189397092831},
+ {66, 165, 245},
+ },
+
+ {
+ {202.34041178860943, 62.5727975926596},
+ {194.31475420052337, 16.263092127403226},
+ {4.540789381659197, 4.547389366225563},
+ {202.59417393479197, 62.529681669860054},
+ {4.547389366225563, 4.540789381659197},
+ {239, 83, 80},
+ },
+
+ {
+ {202.59417393479197, 62.529681669860054},
+ {194.87433226646434, 16.16801598994782},
+ {4.547389366225563, 4.553989350791927},
+ {202.84821511643992, 62.4882415002067},
+ {4.553989350791927, 4.547389366225563},
+ {255, 202, 40},
+ },
+
+ {
+ {202.84821511643992, 62.4882415002067},
+ {195.43452564138033, 16.076635103019896},
+ {4.553989350791927, 4.560589335358291},
+ {203.10252426761141, 62.44847888881831},
+ {4.560589335358291, 4.553989350791927},
+ {102, 187, 106},
+ },
+
+ {
+ {203.10252426761141, 62.44847888881831},
+ {195.99530992345078, 15.988953447137803},
+ {4.560589335358291, 4.5671893199246565},
+ {203.3570903106919, 62.41039556773984},
+ {4.5671893199246565, 4.560589335358291},
+ {171, 71, 188},
+ },
+
+ {
+ {203.35709031069194, 62.41039556773983},
+ {196.5566606851156, 15.904974841682716},
+ {4.567189319924658, 4.573789304491022},
+ {203.6119021568766, 62.373993195867},
+ {4.573789304491022, 4.567189319924658},
+ {38, 198, 218},
+ },
+
+ {
+ {203.6119021568766, 62.373993195867},
+ {197.1185534741381, 15.824702944732365},
+ {4.573789304491022, 4.580389289057386},
+ {203.8669487066536, 62.33927335887393},
+ {4.580389289057386, 4.573789304491022},
+ {255, 110, 64},
+ },
+
+ {
+ {203.8669487066536, 62.33927335887393},
+ {197.68096381467205, 15.74814125290149},
+ {4.580389289057386, 4.586989273623752},
+ {204.12221885028765, 62.30623756914416},
+ {4.586989273623752, 4.580389289057386},
+ {212, 225, 87},
+ },
+
+ {
+ {204.12221885028765, 62.30623756914416},
+ {198.24386720832663, 15.67529310118968},
+ {4.586989273623752, 4.593589258190118},
+ {204.3777014683036, 62.274887265704734},
+ {4.593589258190118, 4.586989273623752},
+ {189, 189, 189},
+ },
+
+ {
+ {204.3777014683036, 62.274887265704734},
+ {198.80723913523357, 15.606161662836087},
+ {4.593589258190118, 4.600189242756482},
+ {204.63338543197096, 62.245223814163545},
+ {4.600189242756482, 4.593589258190118},
+ {92, 107, 192},
+ },
+
+ {
+ {204.63338543197096, 62.245223814163545},
+ {199.37105505511542, 15.540749949181148},
+ {4.600189242756482, 4.606789227322848},
+ {204.88925960378893, 62.21724850664979},
+ {4.606789227322848, 4.600189242756482},
+ {79, 195, 247},
+ },
+
+ {
+ {204.88925960378893, 62.21724850664979},
+ {199.93529040835506, 15.479060809535426},
+ {4.606789227322848, 4.6133892118892135},
+ {205.1453128379711, 62.190962561757736},
+ {4.6133892118892135, 4.606789227322848},
+ {255, 167, 38},
+ },
+
+ {
+ {205.1453128379711, 62.190962561757736},
+ {200.49992061706448, 15.42109693105553},
+ {4.6133892118892135, 4.6199891964555775},
+ {205.4015339809312, 62.166367124493654},
+ {4.6199891964555775, 4.6133892118892135},
+ {66, 165, 245},
+ },
+
+ {
+ {205.4015339809312, 62.166367124493654},
+ {201.06492108615595, 15.366860838627034},
+ {4.6199891964555775, 4.626589181021943},
+ {205.65791187176904, 62.14346326622588},
+ {4.626589181021943, 4.6199891964555775},
+ {239, 83, 80},
+ },
+
+ {
+ {205.65791187176904, 62.14346326622588},
+ {201.6302672044138, 15.316354894754497},
+ {4.626589181021943, 4.633189165588309},
+ {205.91443534275646, 62.12225198463818},
+ {4.633189165588309, 4.626589181021943},
+ {255, 202, 40},
+ },
+
+ {
+ {205.91443534275646, 62.12225198463818},
+ {202.19593434556555, 15.269581299458551},
+ {4.633189165588309, 4.639789150154673},
+ {206.17109321982377, 62.10273420368633},
+ {4.639789150154673, 4.633189165588309},
+ {102, 187, 106},
+ },
+
+ {
+ {206.17109321982377, 62.10273420368633},
+ {202.761897869355, 15.226542090180118},
+ {4.639789150154673, 4.646389134721039},
+ {206.4278743230469, 62.084910773557795},
+ {4.646389134721039, 4.639789150154673},
+ {171, 71, 188},
+ },
+
+ {
+ {206.4278743230469, 62.084910773557795},
+ {203.3281331226162, 15.187239141691535},
+ {4.646389134721039, 4.652989119287405},
+ {206.68476746713378, 62.06878247063473},
+ {4.652989119287405, 4.646389134721039},
+ {38, 198, 218},
+ },
+
+ {
+ {206.68476746713378, 62.06878247063473},
+ {203.89461544034626, 15.151674166015042},
+ {4.652989119287405, 4.659589103853769},
+ {206.94176146191197, 62.054349997460186},
+ {4.659589103853769, 4.652989119287405},
+ {255, 110, 64},
+ },
+
+ {
+ {206.94176146191197, 62.054349997460186},
+ {204.46132014678022, 15.119848712348102},
+ {4.659589103853769, 4.666189088420133},
+ {207.19884511281612, 62.041613982707474},
+ {4.666189088420133, 4.659589103853769},
+ {212, 225, 87},
+ },
+
+ {
+ {207.19884511281617, 62.041613982707474},
+ {205.02822255646643, 15.091764166995972},
+ {4.6661890884201345, 4.6727890729865},
+ {207.45600722137553, 62.03057498115278},
+ {4.6727890729865, 4.6661890884201345},
+ {189, 189, 189},
+ },
+
+ {
+ {207.45600722137553, 62.03057498115278},
+ {205.5952979753409, 15.067421753311265},
+ {4.6727890729865, 4.679389057552864},
+ {207.71323658570157, 62.02123347365103},
+ {4.679389057552864, 4.6727890729865},
+ {92, 107, 192},
+ },
+
+ {
+ {207.71323658570157, 62.02123347365103},
+ {206.16252170180348, 15.046822531640728},
+ {4.679389057552864, 4.685989042119228},
+ {207.97052200097633, 62.0135898671149},
+ {4.685989042119228, 4.679389057552864},
+ {79, 195, 247},
+ },
+
+ {
+ {207.97052200097633, 62.0135898671149},
+ {206.72986902779397, 15.029967399279002},
+ {4.685989042119228, 4.692589026685594},
+ {208.2278522599403, 62.00764449449712},
+ {4.692589026685594, 4.685989042119228},
+ {255, 167, 38},
+ },
+
+ {
+ {208.2278522599403, 62.00764449449712},
+ {207.29731523986834, 15.016857090429554},
+ {4.692589026685594, 4.69918901125196},
+ {208.4852161533804, 62.003397614775984},
+ {4.69918901125196, 4.692589026685594},
+ {66, 165, 245},
+ },
+
+ {
+ {208.4852161533804, 62.003397614775984},
+ {207.86483562027476, 15.00749217617269},
+ {4.69918901125196, 4.705788995818324},
+ {208.74260247061855, 62.00084941294403},
+ {4.705788995818324, 4.69918901125196},
+ {239, 83, 80},
+ },
+
+ {
+ {208.74260247061855, 62.00084941294403},
+ {208.43240544803064, 15.001873064440673},
+ {4.705788995818324, 4.71238898038469},
+ {209, 62},
+ {4.71238898038469, 4.705788995818324},
+ {255, 202, 40},
+ },
+};
+
+void draw(SkCanvas* canvas) {
+ SkRect oval1 = {209 - 86, 101 - 86, 209 + 86, 101 + 86};
+ SkRect oval2 = {209 - 39, 101 - 39, 209 + 39, 101 + 39};
+ for (const auto& wedge : wedges) {
+ SkPath path;
+ path.moveTo(SkDoubleToScalar(wedge.fMove[0]), SkDoubleToScalar(wedge.fMove[1]));
+ path.lineTo(SkDoubleToScalar(wedge.fLine1[0]), SkDoubleToScalar(wedge.fLine1[1]));
+ SkASSERT(wedge.fArc1Angles[0] == wedge.fArc2Angles[1]);
+ SkASSERT(wedge.fArc1Angles[1] == wedge.fArc2Angles[0]);
+ SkScalar start = SkDoubleToScalar(wedge.fArc1Angles[0] * 180.f / SK_ScalarPI);
+ SkScalar end = SkDoubleToScalar(wedge.fArc1Angles[1] * 180.f / SK_ScalarPI);
+ if (end < start) {
+ end += 360;
+ }
+ path.arcTo(oval1, start, end - start, false);
+ path.lineTo(SkDoubleToScalar(wedge.fLine2[0]), SkDoubleToScalar(wedge.fLine2[1]));
+ path.arcTo(oval2, end, start - end, false);
+ path.close();
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setARGB(255, wedge.fRGB[0], wedge.fRGB[1], wedge.fRGB[2]);
+ canvas->drawPath(path, paint);
+ }
+}
+
+} // END FIDDLE
diff --git a/docs/examples/bugoftheday.cpp b/docs/examples/bugoftheday.cpp
new file mode 100644
index 0000000..c1a9896
--- /dev/null
+++ b/docs/examples/bugoftheday.cpp
@@ -0,0 +1,15 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(bugoftheday, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ SkPath path;
+ path.moveTo(10, 10);
+ path.moveTo(75, 75);
+ path.lineTo(150, 75);
+ path.lineTo(150, 150);
+ path.lineTo(75, 150);
+ canvas->drawPath(path, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/checker_board.cpp b/docs/examples/checker_board.cpp
new file mode 100644
index 0000000..424ce4f
--- /dev/null
+++ b/docs/examples/checker_board.cpp
@@ -0,0 +1,27 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(checker_board, 256, 256, false, 0) {
+void checkerboard(SkCanvas* canvas) {
+ SkColor color1 = SK_ColorLTGRAY;
+ SkColor color2 = SK_ColorCYAN;
+ SkScalar scale = 10.0f;
+ SkPath path;
+ path.addRect(0, 0, scale, scale);
+ SkMatrix matrix = SkMatrix::MakeScale(2 * scale, scale);
+ matrix.preSkew(0.5f, 0);
+ SkPaint paint;
+ paint.setPathEffect(SkPath2DPathEffect::Make(matrix, path));
+ paint.setAntiAlias(true);
+ paint.setColor(color2);
+ canvas->clear(color1);
+ SkRect bounds = SkRect::MakeWH(256, 256);
+ bounds.outset(scale, scale);
+ canvas->drawRect(bounds, paint);
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->drawColor(SK_ColorWHITE);
+ checkerboard(canvas);
+}
+} // END FIDDLE
diff --git a/docs/examples/color_filter_vs_colorFilterImageFilter_saveLayer.cpp b/docs/examples/color_filter_vs_colorFilterImageFilter_saveLayer.cpp
new file mode 100644
index 0000000..70fc6c6
--- /dev/null
+++ b/docs/examples/color_filter_vs_colorFilterImageFilter_saveLayer.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(color_filter_vs_colorFilterImageFilter_saveLayer, 256, 128, false, 3) {
+sk_sp<SkColorFilter> saturate() {
+ SkScalar colorMatrix[20] = {1.75, 0, 0, 0, 0,
+ 0, 1.75, 0, 0, 0,
+ 0, 0, 1.75, 0, 0,
+ 0, 0, 0, 1, 0};
+ return SkColorFilters::Matrix(colorMatrix);
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setColorFilter(saturate());
+ canvas->drawImageRect(image, {0, 0, 128, 128}, &paint);
+
+ SkPaint paint2;
+ paint2.setImageFilter(SkColorFilterImageFilter::Make(saturate(), nullptr));
+ SkAutoCanvasRestore autoCanvasRestore(canvas, false);
+ canvas->saveLayer(nullptr, &paint2);
+ canvas->drawImageRect(image, {128, 0, 256, 128}, nullptr);
+}
+} // END FIDDLE
diff --git a/docs/examples/compose_path.cpp b/docs/examples/compose_path.cpp
new file mode 100644
index 0000000..0517ae2
--- /dev/null
+++ b/docs/examples/compose_path.cpp
@@ -0,0 +1,30 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(compose_path, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ const SkScalar intervals[] = {10.0f, 5.0f, 2.0f, 5.0f};
+ size_t count = sizeof(intervals) / sizeof(intervals[0]);
+ SkPaint paint;
+ paint.setPathEffect(
+ SkPathEffect::MakeCompose(SkDashPathEffect::Make(intervals, count, 0.0f),
+ SkDiscretePathEffect::Make(10.0f, 4.0f)));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ paint.setColor(0xff4285F4);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/convex_overstroke_linear_approx_curve.cpp b/docs/examples/convex_overstroke_linear_approx_curve.cpp
new file mode 100644
index 0000000..91516b0
--- /dev/null
+++ b/docs/examples/convex_overstroke_linear_approx_curve.cpp
@@ -0,0 +1,54 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(convex_overstroke_linear_approx_curve, 256, 256, false, 0) {
+#include "math.h"
+
+void draw(SkCanvas* canvas) {
+ const float SCALE = 1;
+ const int WIDTH = 150;
+
+ const float PI = 3.1415926;
+
+ canvas->scale(SCALE, SCALE);
+ canvas->translate(50, 50);
+
+ SkPoint p1 = SkPoint::Make(50, 50);
+ SkPoint p2 = SkPoint::Make(80, 50);
+
+ SkPoint points[10];
+
+ for (int i = 0; i < 10; i++) {
+ points[i] = SkPoint::Make(65 + 15 * cos(i * PI / 10), 50 - 15 * sin(i * PI / 10));
+ }
+
+ SkPath path;
+ path.moveTo(p1);
+ path.lineTo(p2);
+
+ for (int i = 0; i < 10; i++) {
+ path.lineTo(points[i]);
+ }
+ path.lineTo(p1);
+ // path.close();
+
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(WIDTH);
+
+ canvas->drawPath(path, p);
+
+ SkPath fillpath;
+ p.getFillPath(path, &fillpath);
+
+ SkPaint fillp;
+ fillp.setColor(SK_ColorBLACK);
+ fillp.setAntiAlias(true);
+ fillp.setStyle(SkPaint::kStroke_Style);
+ fillp.setStrokeWidth(1);
+
+ canvas->drawPath(fillpath, fillp);
+}
+} // END FIDDLE
diff --git a/docs/examples/convex_overstroke_quad.cpp b/docs/examples/convex_overstroke_quad.cpp
new file mode 100644
index 0000000..345c345
--- /dev/null
+++ b/docs/examples/convex_overstroke_quad.cpp
@@ -0,0 +1,40 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(convex_overstroke_quad, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ const float SCALE = 1;
+ const int WIDTH = 100;
+
+ canvas->scale(SCALE, SCALE);
+ canvas->translate(30, 30);
+
+ SkPoint p1 = SkPoint::Make(50, 50);
+ SkPoint p2 = SkPoint::Make(80, 50);
+
+ SkPoint p3 = SkPoint::Make(65, 30);
+
+ SkPath path;
+ path.moveTo(p1);
+ path.lineTo(p2);
+ path.quadTo(p3, p1);
+ // path.close();
+
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(WIDTH);
+
+ SkPath fillpath;
+ p.getFillPath(path, &fillpath);
+
+ SkPaint fillp;
+ fillp.setColor(SK_ColorBLACK);
+ fillp.setAntiAlias(true);
+ fillp.setStyle(SkPaint::kStroke_Style);
+
+ canvas->drawPath(path, p);
+ canvas->drawPath(fillpath, fillp);
+}
+} // END FIDDLE
diff --git a/docs/examples/count_verbs.cpp b/docs/examples/count_verbs.cpp
new file mode 100644
index 0000000..72181b8
--- /dev/null
+++ b/docs/examples/count_verbs.cpp
@@ -0,0 +1,48 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(count_verbs, 256, 256, false, 0) {
+#include "include/utils/SkTextUtils.h"
+
+static SkPath make_path(const SkFont& font) {
+ SkPath path;
+ const char text[] = "SKIA";
+ SkTextUtils::GetPath(text, strlen(text), SkTextEncoding::kUTF8, 0, 0, font, &path);
+ return path;
+}
+
+static void count_verbs(const SkPath& path, int counts[6]) {
+ SkPath::Iter it(path, false);
+ for (int i = 0; i < 6; ++i) {
+ counts[i] = 0;
+ }
+ while (true) {
+ SkPoint pts[4];
+ SkPath::Verb verb = it.next(pts);
+ if (verb == SkPath::kDone_Verb) {
+ break;
+ }
+ if ((unsigned)verb < 6) {
+ counts[(unsigned)verb]++;
+ }
+ }
+}
+
+void draw(SkCanvas* canvas) {
+ SkFont font(SkTypeface::MakeFromName("DejaVu Sans Mono", SkFontStyle()), 30);
+ SkPath path = make_path(font);
+ int counts[6];
+ count_verbs(path, counts);
+
+ // output results:
+ const char* verbs[6] = {"Move", "Line", "Quad", "Conic", "Cubic", "Close"};
+ SkPoint pt = SkPoint::Make(10.0f, 5.0f + font.getSpacing());
+ SkPaint p;
+ canvas->clear(SK_ColorWHITE);
+ for (int i = 0; i < 6; ++i) {
+ canvas->drawString(SkStringPrintf("%-5s %3d", verbs[i], counts[i]), pt.fX, pt.fY, font,
+ p);
+ pt.fY += font.getSpacing();
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/crbug_663246.cpp b/docs/examples/crbug_663246.cpp
new file mode 100644
index 0000000..b75a06f
--- /dev/null
+++ b/docs/examples/crbug_663246.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(crbug_663246, 384, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ canvas->scale(0.5, 0.5);
+
+ p.setStrokeWidth(195.23635741822847);
+ SkPath path;
+ path.moveTo(488, 182.10368918639688);
+ path.cubicTo(572, 182.10368918639688, 572, 97.61817870911423, 655, 97.61817870911423);
+ p.setColor(SK_ColorGREEN);
+ canvas->drawPath(path, p);
+
+ p.setStrokeWidth(504.6189756548017);
+ path.reset();
+ path.moveTo(20, 252.30948782740091);
+ path.cubicTo(31, 252.30948782740091, 31, 278.79312771879796, 41, 278.79312771879796);
+ p.setColor(SK_ColorRED);
+ canvas->drawPath(path, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/crbug_918512.cpp b/docs/examples/crbug_918512.cpp
new file mode 100644
index 0000000..81578e6
--- /dev/null
+++ b/docs/examples/crbug_918512.cpp
@@ -0,0 +1,27 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(crbug_918512, 256, 256, false, 0) {
+// https://crbug.com/918512
+// Verify that PDF draws correctly.
+void draw(SkCanvas* canvas) {
+ canvas->drawColor(SK_ColorYELLOW);
+ {
+ SkAutoCanvasRestore autoCanvasRestore1(canvas, false);
+ canvas->saveLayer(nullptr, nullptr);
+ canvas->drawColor(SK_ColorCYAN);
+ {
+ SkAutoCanvasRestore autoCanvasRestore2(canvas, false);
+ SkPaint lumaFilter;
+ lumaFilter.setBlendMode(SkBlendMode::kDstIn);
+ lumaFilter.setColorFilter(SkLumaColorFilter::Make());
+ canvas->saveLayer(nullptr, &lumaFilter);
+
+ canvas->drawColor(SK_ColorTRANSPARENT);
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ canvas->drawRect(SkRect{0, 0, 128, 256}, paint);
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/cubics_are_horrible.cpp b/docs/examples/cubics_are_horrible.cpp
new file mode 100644
index 0000000..c95a17c
--- /dev/null
+++ b/docs/examples/cubics_are_horrible.cpp
@@ -0,0 +1,35 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(cubics_are_horrible, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->scale(0.4, 0.4);
+ canvas->translate(175, 175);
+
+ SkPaint p;
+ p.setColor(SK_ColorBLACK);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(400);
+
+ SkPoint p1 = SkPoint::Make(60, -40);
+ SkPoint p2 = SkPoint::Make(120, 150);
+ SkPoint p3 = SkPoint::Make(180, 60);
+
+ SkPath path;
+ path.moveTo(20, 60);
+ path.cubicTo(p1, p2, p3);
+ // path.close();
+
+ SkPath fillpath;
+ p.getFillPath(path, &fillpath);
+ SkPaint fillp;
+ fillp.setColor(SK_ColorMAGENTA);
+ fillp.setAntiAlias(true);
+ fillp.setStyle(SkPaint::kStroke_Style);
+ fillp.setStrokeWidth(0);
+
+ canvas->drawPath(path, p);
+ canvas->drawPath(fillpath, fillp);
+}
+} // END FIDDLE
diff --git a/docs/examples/default.cpp b/docs/examples/default.cpp
new file mode 100644
index 0000000..9899307
--- /dev/null
+++ b/docs/examples/default.cpp
@@ -0,0 +1,14 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(default, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(10);
+
+ canvas->drawLine(20, 20, 236, 236, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/default2.cpp b/docs/examples/default2.cpp
new file mode 100644
index 0000000..2586507
--- /dev/null
+++ b/docs/examples/default2.cpp
@@ -0,0 +1,14 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(default2, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(10);
+
+ canvas->drawLine(20, 20, 100, 100, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/default3.cpp b/docs/examples/default3.cpp
new file mode 100644
index 0000000..f78e033
--- /dev/null
+++ b/docs/examples/default3.cpp
@@ -0,0 +1,27 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(default3, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkPathEffect::MakeSum(SkDiscretePathEffect::Make(10.0f, 4.0f),
+ SkDiscretePathEffect::Make(10.0f, 4.0f, 1245u)));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ paint.setColor(0xff4281A4);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/discrete_path.cpp b/docs/examples/discrete_path.cpp
new file mode 100644
index 0000000..aa4929f
--- /dev/null
+++ b/docs/examples/discrete_path.cpp
@@ -0,0 +1,27 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(discrete_path, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkDiscretePathEffect::Make(10.0f, 4.0f));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ paint.setColor(0xff4285F4);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/dither1.cpp b/docs/examples/dither1.cpp
new file mode 100644
index 0000000..6745aec
--- /dev/null
+++ b/docs/examples/dither1.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(dither1, 256, 100, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkBitmap bm16;
+ bm16.allocPixels(SkImageInfo::Make(32, 32, kRGB_565_SkColorType, kOpaque_SkAlphaType));
+ SkCanvas c16(bm16);
+ SkPaint colorPaint;
+ for (auto dither : {false, true}) {
+ colorPaint.setDither(dither);
+ for (auto colors : {0xFF333333, 0xFF666666, 0xFF999999, 0xFFCCCCCC}) {
+ for (auto mask : {0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFFFFFF}) {
+ colorPaint.setColor(colors & mask);
+ c16.drawRect({0, 0, 8, 4}, colorPaint);
+ c16.translate(8, 0);
+ }
+ c16.translate(-32, 4);
+ }
+ }
+ canvas->scale(8, 8);
+ canvas->drawBitmap(bm16, 0, 0);
+}
+
+} // END FIDDLE
diff --git a/docs/examples/draw_a8_bitmap.cpp b/docs/examples/draw_a8_bitmap.cpp
new file mode 100644
index 0000000..6a45ca1
--- /dev/null
+++ b/docs/examples/draw_a8_bitmap.cpp
@@ -0,0 +1,18 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_a8_bitmap, 256, 256, false, 3) {
+void draw(SkCanvas* canvas) {
+ SkBitmap bitmap;
+ bitmap.allocPixels(SkImageInfo::MakeA8(256, 256));
+ for (int y = 0; y < bitmap.height(); ++y) {
+ for (int x = 0; x < bitmap.width(); ++x) {
+ *bitmap.getAddr8(x, y) = (2 * x + 2 * y) & 0xFF;
+ }
+ }
+ SkPaint paint;
+ paint.setColor(0xFF00FF00);
+ canvas->clear(0xFF000000);
+ canvas->drawBitmap(bitmap, 0, 0, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/draw_image_nine_blur_mask.cpp b/docs/examples/draw_image_nine_blur_mask.cpp
new file mode 100644
index 0000000..2c464e2
--- /dev/null
+++ b/docs/examples/draw_image_nine_blur_mask.cpp
@@ -0,0 +1,11 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_image_nine_blur_mask, 256, 256, false, 6) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 6, false));
+ canvas->clear(0xFFFF4444);
+ canvas->drawImageNine(image.get(), {16, 16, 48, 48}, {8, 8, 248, 248}, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/draw_patch.cpp b/docs/examples/draw_patch.cpp
new file mode 100644
index 0000000..97f9a23
--- /dev/null
+++ b/docs/examples/draw_patch.cpp
@@ -0,0 +1,22 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_patch, 350, 350, false, 6) {
+// draw_patch
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorWHITE);
+ SkPaint p;
+ p.setAntiAlias(true);
+ const SkColor colors[] = {SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
+ SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW};
+ const SkPoint pts[] = {{100.f / 4.f, 0.f}, {3.f * 100.f / 4.f, 100.f}};
+ p.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
+ SkTileMode::kMirror));
+ const SkPoint cubics[] = {{100, 100}, {150, 50}, {250, 150}, {300, 100},
+ {250, 150}, {350, 250}, {300, 300}, {250, 250},
+ {150, 350}, {100, 300}, {50, 250}, {150, 150}};
+ const SkPoint texCoords[] = {
+ {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f, 100.0f}, {0.0f, 100.0f}};
+ canvas->drawPatch(cubics, nullptr, texCoords, SkBlendMode::kSrcOver, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/draw_pixel_array.cpp b/docs/examples/draw_pixel_array.cpp
new file mode 100644
index 0000000..82316eb
--- /dev/null
+++ b/docs/examples/draw_pixel_array.cpp
@@ -0,0 +1,21 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_pixel_array, 256, 256, false, 5) {
+void draw(SkCanvas* canvas) {
+ constexpr int width = 4;
+ constexpr int height = 4;
+ static const uint32_t pixels[height * width] = {
+ 0xFF000000, 0xFF005500, 0xFF00AA00, 0xFF00FF00,
+ 0xFF000055, 0xFF005555, 0xFF00AA55, 0xFF00FF55,
+ 0xFF0000AA, 0xFF0055AA, 0xFF00AAAA, 0xFF00FFAA,
+ 0xFF0000FF, 0xFF0055FF, 0xFF00AAFF, 0xFF00FFFF,
+ };
+ SkPixmap pixmap(SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType),
+ pixels, sizeof(uint32_t) * width);
+ sk_sp<SkImage> img = SkImage::MakeRasterCopy(pixmap);
+
+ canvas->scale(16, 16);
+ canvas->drawImage(img, 6, 6);
+}
+} // END FIDDLE
diff --git a/docs/examples/draw_pixel_array_nocopy.cpp b/docs/examples/draw_pixel_array_nocopy.cpp
new file mode 100644
index 0000000..bdf4d79
--- /dev/null
+++ b/docs/examples/draw_pixel_array_nocopy.cpp
@@ -0,0 +1,22 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_pixel_array_nocopy, 256, 256, false, 5) {
+constexpr int kWidth = 4;
+constexpr int kHeight = 4;
+static const uint32_t kPixels[kHeight * kWidth] = {
+ 0xFF000000, 0xFF005500, 0xFF00AA00, 0xFF00FF00,
+ 0xFF000055, 0xFF005555, 0xFF00AA55, 0xFF00FF55,
+ 0xFF0000AA, 0xFF0055AA, 0xFF00AAAA, 0xFF00FFAA,
+ 0xFF0000FF, 0xFF0055FF, 0xFF00AAFF, 0xFF00FFFF,
+};
+
+void draw(SkCanvas* canvas) {
+ SkPixmap pixmap(SkImageInfo::Make(kWidth, kHeight, kN32_SkColorType, kPremul_SkAlphaType),
+ kPixels, sizeof(uint32_t) * kWidth);
+ sk_sp<SkImage> img = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
+
+ canvas->scale(16, 16);
+ canvas->drawImage(img, 6, 6);
+}
+} // END FIDDLE
diff --git a/docs/examples/draw_pixel_array_with_copy.cpp b/docs/examples/draw_pixel_array_with_copy.cpp
new file mode 100644
index 0000000..43db078
--- /dev/null
+++ b/docs/examples/draw_pixel_array_with_copy.cpp
@@ -0,0 +1,21 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_pixel_array_with_copy, 256, 256, false, 5) {
+void draw(SkCanvas* canvas) {
+ constexpr int width = 4;
+ constexpr int height = 4;
+ const uint32_t pixels[height * width] = {
+ 0xFF000000, 0xFF005500, 0xFF00AA00, 0xFF00FF00,
+ 0xFF000055, 0xFF005555, 0xFF00AA55, 0xFF00FF55,
+ 0xFF0000AA, 0xFF0055AA, 0xFF00AAAA, 0xFF00FFAA,
+ 0xFF0000FF, 0xFF0055FF, 0xFF00AAFF, 0xFF00FFFF,
+ };
+ SkPixmap pixmap(SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType),
+ pixels, sizeof(uint32_t) * width);
+ sk_sp<SkImage> img = SkImage::MakeRasterCopy(pixmap);
+
+ canvas->scale(16,16);
+ canvas->drawImage(img, 6, 6);
+}
+} // END FIDDLE
diff --git a/docs/examples/draw_text_fails.cpp b/docs/examples/draw_text_fails.cpp
new file mode 100644
index 0000000..262090a
--- /dev/null
+++ b/docs/examples/draw_text_fails.cpp
@@ -0,0 +1,8 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_text_fails, 256, 46, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->drawString("ABCDE ⒶⒷⒸⒹⒺ 𝓐𝓑𝓒𝓓𝓔", 18, 32, SkFont(nullptr, 12), SkPaint());
+}
+} // END FIDDLE
diff --git a/docs/examples/draw_vertices.cpp b/docs/examples/draw_vertices.cpp
new file mode 100644
index 0000000..1ebe48e
--- /dev/null
+++ b/docs/examples/draw_vertices.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(draw_vertices, 256, 256, false, 6) {
+// draw_vertices
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setAntiAlias(true);
+
+ SkPoint pts[3] = {{64, 32}, {0, 224}, {128, 224}};
+ SkColor colors[3] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};
+ canvas->drawVertices(
+ SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts, nullptr, colors),
+ SkBlendMode::kSrcOver, p);
+
+ canvas->translate(120, 0);
+
+ p.setShader(image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
+ SkPoint texs[3] = {{0, 0}, {0, 128}, {64, 256}};
+ canvas->drawVertices(
+ SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts, texs, nullptr),
+ SkBlendMode::kSrcOver, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/drawarcs.cpp b/docs/examples/drawarcs.cpp
new file mode 100644
index 0000000..905690e
--- /dev/null
+++ b/docs/examples/drawarcs.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(drawarcs, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(8);
+
+ SkPath path;
+ SkRandom rand;
+
+ for (int i = 0; i < 100; ++i) {
+ SkScalar x = rand.nextUScalar1() * 200;
+ SkScalar y = rand.nextUScalar1() * 200;
+
+ path.rewind();
+ path.addArc(SkRect::MakeXYWH(x, y, 70, 70), rand.nextUScalar1() * 360,
+ rand.nextUScalar1() * 360);
+ paint.setColor(rand.nextU() | 0xFF000000);
+ canvas->drawPath(path, paint);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/example3ps.cpp b/docs/examples/example3ps.cpp
new file mode 100644
index 0000000..53503f0
--- /dev/null
+++ b/docs/examples/example3ps.cpp
@@ -0,0 +1,109 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(example3ps, 320, 256, false, 0) {
+static SkMatrix setpsmatrix(float sx, float kx, float ky, float sy, float tx, float ty, int h) {
+ SkMatrix m;
+
+ m.setAll(sx, -kx, -tx * sx - (ty - h) * kx, -ky, sy, (ty - h) * sy + tx * ky, 0, 0, 1);
+ return m;
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->save();
+ canvas->scale(15, -15);
+ canvas->translate(0, -28);
+ SkPath path;
+ path.moveTo(2, 2);
+ path.lineTo(3, 3);
+ path.lineTo(3, 4);
+ path.lineTo(2, 4);
+ path.lineTo(1, 5);
+ path.close();
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setStrokeWidth(0.1f);
+
+ canvas->save();
+ canvas->translate(0, 18);
+ p.setColor(SK_ColorGRAY);
+ canvas->drawPath(path, p);
+ canvas->restore();
+
+ p.setStyle(SkPaint::kStroke_Style);
+ canvas->save();
+ canvas->translate(8, 19);
+ canvas->rotate(90);
+ p.setColor(SK_ColorRED);
+ canvas->drawPath(path, p);
+ canvas->restore();
+
+ canvas->save();
+ canvas->translate(5, 23);
+ canvas->rotate(-90);
+ p.setColor(SK_ColorBLUE);
+ canvas->drawPath(path, p);
+ canvas->restore();
+
+ canvas->save();
+ canvas->translate(14, 18);
+ canvas->scale(-1, 1);
+ p.setColor(0xFF007F00);
+ canvas->drawPath(path, p);
+ canvas->restore();
+ canvas->restore();
+
+ canvas->scale(15, 15);
+ canvas->translate(0, 24);
+
+ SkMatrix m;
+ unsigned char d[] = {0x00, 0x00, 0x00, 0x00, 0xff, 0xff};
+ sk_sp<SkData> data = SkData::MakeWithoutCopy((unsigned char*)d, sizeof(d));
+ SkImageInfo info =
+ SkImageInfo::Make(3, 2, SkColorType::kGray_8_SkColorType, kOpaque_SkAlphaType);
+ sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, 3);
+
+ SkPaint bp;
+ canvas->save();
+ m = setpsmatrix(1, 0, 0, 1, -1, -24, 2);
+ // m.setAll(1, 0, -1, 0, 1, -24, 0, 0, 1);
+ canvas->concat(m);
+ canvas->drawImage(image, 0, 0, &bp);
+ canvas->restore();
+
+ canvas->save();
+ m = setpsmatrix(0, 1, 1, 0, -24, -5, 2);
+ // m.setAll(0, -1, 5, -1, 0, -22, 0, 0, 1);
+ canvas->concat(m);
+ canvas->drawImage(image, 0, 0, &bp);
+ canvas->restore();
+
+ canvas->save();
+ m = setpsmatrix(0, 1, -1, 0, 27, -8, 2);
+ // m.setAll(0, -1, 8, 1, 0, -25, 0, 0, 1);
+ canvas->concat(m);
+ canvas->drawImage(image, 0, 0, &bp);
+ canvas->restore();
+
+ canvas->save();
+ m = setpsmatrix(0, -1, -1, 0, -24, 13, 2);
+ // m.setAll(0, 1, 9, -1, 0, -22, 0, 0, 1);
+ canvas->concat(m);
+ canvas->drawImage(image, 0, 0, &bp);
+ canvas->restore();
+
+ canvas->save();
+ m = setpsmatrix(-1, 0, 0, -1, 17, 26, 2);
+ // m.setAll(-1, 0, 15, 0, -1, -22, 0, 0, 1);
+ canvas->concat(m);
+ canvas->drawImage(image, 0, 0, &bp);
+ canvas->restore();
+
+ canvas->save();
+ m = setpsmatrix(-1, 0, 0, 1, 21, -24, 2);
+ // m.setAll(-1, 0, 19, 0, 1, -24, 0, 0, 1);
+ canvas->concat(m);
+ canvas->drawImage(image, 0, 0, &bp);
+ canvas->restore();
+}
+} // END FIDDLE
diff --git a/docs/examples/f16to8888busted.cpp b/docs/examples/f16to8888busted.cpp
new file mode 100644
index 0000000..c58928f
--- /dev/null
+++ b/docs/examples/f16to8888busted.cpp
@@ -0,0 +1,19 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(f16to8888busted, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ // Create the linear-rgb color space and the image info
+ sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGBLinear();
+ SkImageInfo info = SkImageInfo::Make(100, 100, SkColorType::kRGBA_F16_SkColorType,
+ SkAlphaType::kPremul_SkAlphaType, colorSpace);
+
+ sk_sp<SkSurface> offscreen = SkSurface::MakeRaster(info);
+ SkPaint paint;
+ offscreen->getCanvas()->drawRect(SkRect::MakeXYWH(25, 25, 50, 50), paint);
+
+ // Take a snapshot from surface and draw it on the canvas
+ sk_sp<SkImage> img = offscreen->makeImageSnapshot();
+ canvas->drawImageRect(img, SkRect::MakeWH(100, 100), nullptr);
+}
+} // END FIDDLE
diff --git a/docs/examples/f16to8888drawImageBug.cpp b/docs/examples/f16to8888drawImageBug.cpp
new file mode 100644
index 0000000..c232f42
--- /dev/null
+++ b/docs/examples/f16to8888drawImageBug.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(f16to8888drawImageBug, 256, 256, false, 0) {
+// f16to8888drawImageBug
+void draw(SkCanvas* canvas) {
+ sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGBLinear();
+
+ SkImageInfo imageInfo =
+ SkImageInfo::Make(100, 100, kRGBA_F16_SkColorType, kPremul_SkAlphaType, colorSpace);
+ sk_sp<SkSurface> surface = SkSurface::MakeRaster(imageInfo);
+ SkPaint p;
+ surface->getCanvas()->drawRect(SkRect::MakeXYWH(20, 20, 40, 40), p);
+
+ sk_sp<SkColorSpace> colorSpace2 = SkColorSpace::MakeSRGB();
+
+ SkImageInfo imageInfo2 =
+ SkImageInfo::Make(100, 100, kN32_SkColorType, kPremul_SkAlphaType, colorSpace2);
+ sk_sp<SkSurface> surface2 = SkSurface::MakeRaster(imageInfo2);
+ surface2->getCanvas()->drawImage(surface->makeImageSnapshot(), 0, 0);
+
+ canvas->drawImage(surface->makeImageSnapshot(), 0, 0);
+ canvas->drawImage(surface2->makeImageSnapshot(), 50, 0);
+}
+} // END FIDDLE
diff --git a/docs/examples/failing_example.cpp b/docs/examples/failing_example.cpp
new file mode 100644
index 0000000..5d759d7
--- /dev/null
+++ b/docs/examples/failing_example.cpp
@@ -0,0 +1,14 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(failing_example, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(10);
+
+ canvas->drawLine(20, 20, 100, 100, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/fivearcs.cpp b/docs/examples/fivearcs.cpp
new file mode 100644
index 0000000..374b9fb
--- /dev/null
+++ b/docs/examples/fivearcs.cpp
@@ -0,0 +1,44 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(fivearcs, 256, 128, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SkColorSetARGB(255, 255, 255, 255));
+ SkPaint ovalPaint;
+ ovalPaint.setAntiAlias(true);
+ ovalPaint.setStyle(SkPaint::kStroke_Style);
+ SkPaint arcPaint(ovalPaint);
+ arcPaint.setStrokeWidth(5);
+ arcPaint.setColor(SK_ColorBLUE);
+ SkRect oval = {8, 8, 56, 56};
+
+ canvas->drawOval(oval, ovalPaint);
+ SkPath arcPath;
+ arcPath.arcTo(oval, 0, 90, false);
+ canvas->drawPath(arcPath, arcPaint);
+
+ canvas->translate(64, 0);
+ canvas->drawOval(oval, ovalPaint);
+ canvas->drawArc(oval, 0, 90, false, arcPaint);
+
+ canvas->translate(64, 0);
+ canvas->drawOval(oval, ovalPaint);
+ arcPath.reset();
+ arcPath.addArc(oval, 0, 90);
+ canvas->drawPath(arcPath, arcPaint);
+
+ canvas->translate(-96, 64);
+ canvas->drawOval(oval, ovalPaint);
+ arcPath.reset();
+ arcPath.moveTo({56, 32});
+ arcPath.arcTo({56, 56}, {32, 56}, 24);
+ canvas->drawPath(arcPath, arcPaint);
+
+ canvas->translate(64, 0);
+ canvas->drawOval(oval, ovalPaint);
+ arcPath.reset();
+ arcPath.moveTo({56, 32});
+ arcPath.arcTo({24, 24}, 0, SkPath::kSmall_ArcSize, SkPathDirection::kCW, {32, 56});
+ canvas->drawPath(arcPath, arcPaint);
+}
+} // END FIDDLE
diff --git a/docs/examples/flag_us_1792.cpp b/docs/examples/flag_us_1792.cpp
new file mode 100644
index 0000000..bb258ee
--- /dev/null
+++ b/docs/examples/flag_us_1792.cpp
@@ -0,0 +1,28 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(flag_us_1792, 486, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ canvas->clear(SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF));
+ canvas->scale(256.0f / 3900, 256.0f / 3900);
+ paint.setColor(SkColorSetARGB(0xFF, 0xB2, 0x22, 0x34));
+ for (int s = 0; s < 13; s += 2) {
+ canvas->drawIRect({0, s * 300, 7410, (s + 1) * 300}, paint);
+ }
+ paint.setColor(SkColorSetARGB(0xFF, 0x3C, 0x3B, 0x6E));
+ canvas->drawIRect({0, 0, 2964, 2100}, paint);
+ paint.setColor(SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF));
+ paint.setAntiAlias(true);
+ SkPath star;
+ SkParsePath::FromSVGString("M 0 -150 L 88 121 L -143 -46 L 143 -46 L -88 121 Z", &star);
+ for (int i = 0; i < 13; ++i) {
+ SkMatrix matrix = SkMatrix::MakeTrans(1482, 1050);
+ matrix.preRotate((360.0 / 13) * i);
+ matrix.preTranslate(0, -785);
+ SkAutoCanvasRestore autoCanvasRestore(canvas, true);
+ canvas->concat(matrix);
+ canvas->drawPath(star, paint);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/flag_us_1960.cpp b/docs/examples/flag_us_1960.cpp
new file mode 100644
index 0000000..5b005df
--- /dev/null
+++ b/docs/examples/flag_us_1960.cpp
@@ -0,0 +1,32 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(flag_us_1960, 486, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ canvas->clear(SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF));
+ canvas->scale(256.0f / 3900, 256.0f / 3900);
+ paint.setColor(SkColorSetARGB(0xFF, 0xB2, 0x22, 0x34));
+ for (int s = 0; s < 13; s += 2) {
+ canvas->drawIRect({0, s * 300, 7410, (s + 1) * 300}, paint);
+ }
+ paint.setColor(SkColorSetARGB(0xFF, 0x3C, 0x3B, 0x6E));
+ canvas->drawIRect({0, 0, 2964, 2100}, paint);
+ paint.setColor(SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF));
+ paint.setAntiAlias(true);
+ SkPath star;
+ SkParsePath::FromSVGString(
+ "M 0 -120 L 70.5342 97.0819 L -114.127 -37.082 L 114.127 -37.0821 L -70.5342 "
+ "97.0819 Z",
+ &star);
+ for (int x = 1; x < 12; ++x) {
+ for (int y = 1; y < 10; ++y) {
+ if ((x + y) % 2 == 0) {
+ SkAutoCanvasRestore autoCanvasRestore(canvas, true);
+ canvas->translate(x * 247, y * 210);
+ canvas->drawPath(star, paint);
+ }
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/fluttershadow.cpp b/docs/examples/fluttershadow.cpp
new file mode 100644
index 0000000..a3c395f
--- /dev/null
+++ b/docs/examples/fluttershadow.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(fluttershadow, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setAntiAlias(true);
+ SkPath path;
+ path.moveTo(50.0, 50.0);
+
+ // Comment the next 4 lines, and the shadow will draw.
+ path.lineTo(60.0, 50.0);
+ path.lineTo(60.0, 60.0);
+ path.lineTo(70.0, 60.0);
+ path.lineTo(70.0, 50.0);
+
+ path.lineTo(150.0, 50.0);
+ path.lineTo(150.0, 150.0);
+ path.lineTo(50.0, 150.0);
+ path.close();
+ p.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 3));
+ canvas->drawPath(path, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/gamma_mask_filter.cpp b/docs/examples/gamma_mask_filter.cpp
new file mode 100644
index 0000000..82fcbc9
--- /dev/null
+++ b/docs/examples/gamma_mask_filter.cpp
@@ -0,0 +1,21 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(gamma_mask_filter, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ const char text[] = "Skia";
+ canvas->drawColor(SK_ColorWHITE);
+
+ SkFont font(nullptr, 80);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ canvas->drawString(text, 16, 80, font, paint);
+
+ paint.setMaskFilter(sk_sp<SkMaskFilter>(SkTableMaskFilter::CreateGamma(4.0f)));
+ canvas->drawString(text, 16, 160, font, paint);
+
+ paint.setMaskFilter(sk_sp<SkMaskFilter>(SkTableMaskFilter::CreateGamma(0.25f)));
+ canvas->drawString(text, 16, 240, font, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/getLocalBounds_broken.cpp b/docs/examples/getLocalBounds_broken.cpp
new file mode 100644
index 0000000..22f86ca
--- /dev/null
+++ b/docs/examples/getLocalBounds_broken.cpp
@@ -0,0 +1,19 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(getLocalBounds_broken, 256, 256, true, 0) {
+void draw(SkCanvas* canvas) {
+ // SkCanvas local(256, 256);
+ // canvas = &local;
+ SkRect bounds = canvas->getLocalClipBounds();
+ SkDebugf("left:%g top:%g right:%g bottom:%g\n", bounds.fLeft, bounds.fTop, bounds.fRight,
+ bounds.fBottom);
+ SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230}};
+ SkPath clipPath;
+ clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
+ canvas->clipPath(clipPath);
+ bounds = canvas->getLocalClipBounds();
+ SkDebugf("left:%g top:%g right:%g bottom:%g\n", bounds.fLeft, bounds.fTop, bounds.fRight,
+ bounds.fBottom);
+}
+} // END FIDDLE
diff --git a/docs/examples/getLocalBounds_working.cpp b/docs/examples/getLocalBounds_working.cpp
new file mode 100644
index 0000000..390700c
--- /dev/null
+++ b/docs/examples/getLocalBounds_working.cpp
@@ -0,0 +1,19 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(getLocalBounds_working, 256, 256, true, 0) {
+void draw(SkCanvas* canvas) {
+ SkCanvas local(256, 256);
+ canvas = &local;
+ SkRect bounds = canvas->getLocalClipBounds();
+ SkDebugf("left:%g top:%g right:%g bottom:%g\n", bounds.fLeft, bounds.fTop, bounds.fRight,
+ bounds.fBottom);
+ SkPoint clipPoints[] = {{30, 130}, {120, 130}, {120, 230}};
+ SkPath clipPath;
+ clipPath.addPoly(clipPoints, SK_ARRAY_COUNT(clipPoints), true);
+ canvas->clipPath(clipPath);
+ bounds = canvas->getLocalClipBounds();
+ SkDebugf("left:%g top:%g right:%g bottom:%g\n", bounds.fLeft, bounds.fTop, bounds.fRight,
+ bounds.fBottom);
+}
+} // END FIDDLE
diff --git a/docs/examples/gpu8888diff.cpp b/docs/examples/gpu8888diff.cpp
new file mode 100644
index 0000000..1854da5
--- /dev/null
+++ b/docs/examples/gpu8888diff.cpp
@@ -0,0 +1,32 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(gpu8888diff, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->scale(16, 16);
+ SkBitmap bitmap;
+ SkImageInfo imageInfo =
+ SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ bitmap.allocPixels(imageInfo);
+ SkCanvas offscreen(bitmap);
+ offscreen.clear(SK_ColorGREEN);
+ canvas->drawBitmap(bitmap, 0, 0);
+ offscreen.clear(SK_ColorGRAY);
+ canvas->drawBitmap(bitmap, 2, 2);
+ auto pack8888 = [](unsigned a, unsigned r, unsigned g, unsigned b) -> uint32_t {
+ return (a << 24) | (b << 16) | (g << 8) | (r << 0);
+ };
+ uint32_t red8888[] = {pack8888(0xFF, 0xFF, 0x0, 0x0), pack8888(0xFF, 0xbb, 0x0, 0x0),
+ pack8888(0xFF, 0x99, 0x0, 0x0), pack8888(0xFF, 0x55, 0x0, 0x0)};
+ uint32_t blue8888[] = {pack8888(0xFF, 0x0, 0x0, 0x0FF), pack8888(0xFF, 0x0, 0x0, 0x0bb),
+ pack8888(0xFF, 0x0, 0x0, 0x099), pack8888(0xFF, 0x0, 0x0, 0x055)};
+ SkPixmap redPixmap(imageInfo, &red8888, 8);
+ if (bitmap.writePixels(redPixmap, 0, 0)) {
+ canvas->drawBitmap(bitmap, 4, 4);
+ }
+ SkPixmap bluePixmap(imageInfo, &blue8888, 8);
+ if (bitmap.writePixels(bluePixmap, 0, 0)) {
+ canvas->drawBitmap(bitmap, 6, 6);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/gpuconicbug.cpp b/docs/examples/gpuconicbug.cpp
new file mode 100644
index 0000000..7e7e38c
--- /dev/null
+++ b/docs/examples/gpuconicbug.cpp
@@ -0,0 +1,30 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(gpuconicbug, 300, 200, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPath path;
+ path.moveTo(SkBits2Float(0x43507c37), SkBits2Float(0x4278037b)); // 208.485f, 62.0034f
+ path.lineTo(SkBits2Float(0x434fdd66), SkBits2Float(0x41701eb0)); // 207.865f, 15.0075f
+ path.lineTo(SkBits2Float(0x434fdd67), SkBits2Float(0x41701eb0)); // 207.865f, 15.0075f
+ path.conicTo(
+ SkBits2Float(0x4350260c), SkBits2Float(0x41700f50), SkBits2Float(0x43506eb3),
+ SkBits2Float(0x417007a8),
+ SkBits2Float(0x3f7fffa5)); // 208.149f, 15.0037f, 208.432f, 15.0019f, 0.999995f
+ path.lineTo(SkBits2Float(0x4350be1b), SkBits2Float(0x427800df)); // 208.743f, 62.0009f
+ path.lineTo(SkBits2Float(0x4350be1b), SkBits2Float(0x427800de)); // 208.743f, 62.0008f
+ path.conicTo(
+ SkBits2Float(0x43509d29), SkBits2Float(0x427801bc), SkBits2Float(0x43507c38),
+ SkBits2Float(0x42780379),
+ SkBits2Float(0x3f7fffa5)); // 208.614f, 62.0017f, 208.485f, 62.0034f, 0.999995f
+ path.lineTo(SkBits2Float(0x43507c37), SkBits2Float(0x4278037b)); // 208.485f, 62.0034f
+ path.close();
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ canvas->drawPath(path, paint);
+ canvas->scale(.533333333333333f, .5333333333333f);
+ paint.setColor(SK_ColorRED);
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/homogeneous.cpp b/docs/examples/homogeneous.cpp
new file mode 100644
index 0000000..cbf1119
--- /dev/null
+++ b/docs/examples/homogeneous.cpp
@@ -0,0 +1,30 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(homogeneous, 256, 256, false, 3) {
+void draw(SkCanvas* canvas) {
+ SkPoint3 src[] = {{3, 3, 1}, {8, 2, 2}, {5, 0, 4}, {0, 1, 3},
+ {3, 7, 1}, {8, 6, 2}, {5, 4, 4}, {0, 5, 3}};
+ int lines[] = {0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7};
+ constexpr int count = SK_ARRAY_COUNT(src);
+ auto debugster = [=](SkPoint3 src[]) -> void {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(lines); i += 2) {
+ const SkPoint3& s = src[lines[i]];
+ const SkPoint3& e = src[lines[i + 1]];
+ SkPaint paint;
+ paint.setARGB(77, 23, 99, 154);
+ canvas->drawLine(s.fX / s.fZ, s.fY / s.fZ, e.fX / e.fZ, e.fY / e.fZ, paint);
+ }
+ };
+ canvas->save();
+ canvas->translate(5, 5);
+ canvas->scale(15, 15);
+ debugster(src);
+ canvas->restore();
+ canvas->translate(128, 128);
+ SkMatrix matrix;
+ matrix.setAll(15, 0, 0, 0, 15, 0, -0.08, 0.04, 1);
+ matrix.mapHomogeneousPoints(src, src, count);
+ debugster(src);
+}
+} // END FIDDLE
diff --git a/docs/examples/image_subsets_get_different_uids.cpp b/docs/examples/image_subsets_get_different_uids.cpp
new file mode 100644
index 0000000..cd96bbc
--- /dev/null
+++ b/docs/examples/image_subsets_get_different_uids.cpp
@@ -0,0 +1,12 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(image_subsets_get_different_uids, 128, 128, true, 5) {
+// image_subsets_get_different_uids
+void draw(SkCanvas*) {
+ SkIRect r{0, 0, 10, 10};
+ auto s1 = image->makeSubset(r);
+ auto s2 = image->makeSubset(r);
+ SkDebugf("%u\n%u\n", s1->uniqueID(), s2->uniqueID());
+}
+} // END FIDDLE
diff --git a/docs/examples/image_to_bitmap_does_not_preserve_genid.cpp b/docs/examples/image_to_bitmap_does_not_preserve_genid.cpp
new file mode 100644
index 0000000..3ddeab4
--- /dev/null
+++ b/docs/examples/image_to_bitmap_does_not_preserve_genid.cpp
@@ -0,0 +1,12 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(image_to_bitmap_does_not_preserve_genid, 128, 128, true, 5) {
+// image_to_bitmap_does_not_preserve_genid
+void draw(SkCanvas* canvas) {
+ SkBitmap bm1, bm2;
+ image->asLegacyBitmap(&bm1, SkImage::kRO_LegacyBitmapMode);
+ image->asLegacyBitmap(&bm2, SkImage::kRO_LegacyBitmapMode);
+ SkDebugf("%u\n%u\n", bm1.getGenerationID(), bm2.getGenerationID());
+}
+} // END FIDDLE
diff --git a/docs/examples/inlinepixmapconstructor.cpp b/docs/examples/inlinepixmapconstructor.cpp
new file mode 100644
index 0000000..1fb719c
--- /dev/null
+++ b/docs/examples/inlinepixmapconstructor.cpp
@@ -0,0 +1,12 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(inlinepixmapconstructor, 256, 256, true, 3) {
+void draw(SkCanvas* canvas) {
+ SkDebugf("image alpha only = %s\n", image->isAlphaOnly() ? "true" : "false");
+ SkPMColor pmColors = 0;
+ sk_sp<SkImage> copy =
+ SkImage::MakeRasterCopy({SkImageInfo::MakeA8(1, 1), (uint8_t*)&pmColors, 1});
+ SkDebugf("copy alpha only = %s\n", copy->isAlphaOnly() ? "true" : "false");
+}
+} // END FIDDLE
diff --git a/docs/examples/issue640176.cpp b/docs/examples/issue640176.cpp
new file mode 100644
index 0000000..4906a24
--- /dev/null
+++ b/docs/examples/issue640176.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(issue640176, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ float startAngle = -0.5235985, endAngle = -2.439e-4, radius = 120;
+
+ canvas->translate(radius, radius);
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(radius * cos(startAngle), radius * sin(startAngle));
+ SkRect oval = {-radius, -radius, radius, radius};
+ path.arcTo(oval, startAngle * 180 / 3.14159265359,
+ (endAngle - startAngle) * 180 / 3.14159265359, false);
+ canvas->drawPath(path, p);
+
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setColor(SK_ColorGREEN);
+ canvas->drawPath(path, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/kLow_SkFilterQuality.cpp b/docs/examples/kLow_SkFilterQuality.cpp
new file mode 100644
index 0000000..119c54e
--- /dev/null
+++ b/docs/examples/kLow_SkFilterQuality.cpp
@@ -0,0 +1,19 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(kLow_SkFilterQuality, 192, 192, false, 0) {
+void draw(SkCanvas* canvas) {
+ static const uint32_t pixels[9] = {
+ 0xFFFF0000, 0xFFFFFFFF, 0xFF00FF00, 0xFFFFFFFF, 0xFF000000,
+ 0xFFFFFFFF, 0xFF808080, 0xFFFFFFFF, 0xFF0000FF,
+ };
+ SkBitmap bm;
+ bm.installPixels(SkImageInfo::MakeN32Premul(3, 3), (void*)pixels, 12);
+ bm.setImmutable();
+ SkPaint paint;
+ paint.setFilterQuality(kLow_SkFilterQuality);
+ // paint.setMaskFilter(SkBlurMaskFilter::Make(
+ // kNormal_SkBlurStyle, 3.375, SkBlurMaskFilter::kHighQuality_BlurFlag));
+ canvas->drawBitmapRect(bm, {64, 64, 128, 128}, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/maddash.cpp b/docs/examples/maddash.cpp
new file mode 100644
index 0000000..7d5ee8e
--- /dev/null
+++ b/docs/examples/maddash.cpp
@@ -0,0 +1,17 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(maddash, 400, 200, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(380);
+
+ SkScalar intvls[] = {2.5, 10000};
+ p.setPathEffect(SkDashPathEffect::Make(intvls, 2, 0));
+
+ canvas->drawCircle(0, 100, 200, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/makeRasterImage_fail.cpp b/docs/examples/makeRasterImage_fail.cpp
new file mode 100644
index 0000000..ba7733a
--- /dev/null
+++ b/docs/examples/makeRasterImage_fail.cpp
@@ -0,0 +1,6 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(makeRasterImage_fail, 256, 256, false, 5) {
+void draw(SkCanvas* canvas) { canvas->drawImage(image->makeRasterImage(), 0, 0); }
+} // END FIDDLE
diff --git a/docs/examples/mapradius.cpp b/docs/examples/mapradius.cpp
new file mode 100644
index 0000000..e5b03d7
--- /dev/null
+++ b/docs/examples/mapradius.cpp
@@ -0,0 +1,33 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(mapradius, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ SkMatrix matrix;
+ const SkPoint center = {128, 103};
+ matrix.setScale(2, .5f, center.fX, center.fY);
+ matrix.postRotate(45, center.fX, center.fY);
+ const SkScalar circleRadius = 60;
+ SkScalar mappedRadius = matrix.mapRadius(circleRadius);
+ SkVector minorAxis, majorAxis;
+ matrix.mapVector(0, circleRadius, &minorAxis);
+ matrix.mapVector(circleRadius, 0, &majorAxis);
+ paint.setColor(SK_ColorRED);
+ canvas->drawLine(40, 240, 40 + minorAxis.length(), 240, paint);
+ canvas->drawLine(42 + minorAxis.length(), 240, 42 + minorAxis.length() + majorAxis.length(),
+ 240, paint);
+ paint.setColor(SK_ColorBLACK);
+ canvas->drawLine(center.fX, center.fY, center.fX + mappedRadius, center.fY, paint);
+ canvas->drawLine(center.fX, center.fY, center.fX, center.fY + mappedRadius, paint);
+ canvas->drawLine(40, 220, 40 + mappedRadius, 220, paint);
+ canvas->drawLine(42 + mappedRadius, 220, 42 + mappedRadius * 2, 220, paint);
+ canvas->concat(matrix);
+ canvas->drawCircle(center.fX, center.fY, circleRadius, paint);
+ paint.setColor(SK_ColorRED);
+ canvas->drawLine(center.fX, center.fY, center.fX + circleRadius, center.fY, paint);
+ canvas->drawLine(center.fX, center.fY, center.fX, center.fY + circleRadius, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/massive_coordinates_svg.cpp b/docs/examples/massive_coordinates_svg.cpp
new file mode 100644
index 0000000..2e67496
--- /dev/null
+++ b/docs/examples/massive_coordinates_svg.cpp
@@ -0,0 +1,29 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(massive_coordinates_svg, 800, 600, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ SkRect r = {0, 0, 800, 590};
+ paint.setColor(SK_ColorGREEN);
+ canvas->drawRect(r, paint);
+
+ canvas->clipRect(r);
+
+ paint.setColor(SK_ColorBLACK);
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(1);
+ SkPath path;
+ path.moveTo(-1000, 12345678901234567890.f);
+ path.lineTo(200, 200);
+ canvas->drawPath(path, paint);
+
+ path.reset();
+ path.moveTo(600, 400);
+ path.lineTo(1000, -9.8765432109876543210e+19f);
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/measure_text_bounds.cpp b/docs/examples/measure_text_bounds.cpp
new file mode 100644
index 0000000..49b00d2
--- /dev/null
+++ b/docs/examples/measure_text_bounds.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(measure_text_bounds, 256, 128, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorWHITE);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkFont font(nullptr, 64, 1.25f, -0.25f);
+
+ float x = 32.0f;
+ float y = 88.0f;
+ const char text[] = "Skia";
+
+ SkRect bounds;
+ (void)font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
+
+ canvas->drawRect(bounds.makeOffset(x, y), paint);
+
+ paint.setColor(SK_ColorWHITE);
+ canvas->drawString(text, x, y, font, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/no_gpu_blur.cpp b/docs/examples/no_gpu_blur.cpp
new file mode 100644
index 0000000..b7d60df
--- /dev/null
+++ b/docs/examples/no_gpu_blur.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(no_gpu_blur, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkBitmap alpha, bitmap;
+ bitmap.allocN32Pixels(100, 100);
+ SkCanvas offscreen(bitmap);
+ offscreen.clear(0);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(SK_ColorBLUE);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(20);
+ offscreen.drawCircle(50, 50, 39, paint);
+ offscreen.flush();
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3));
+ SkIPoint offset;
+ bitmap.extractAlpha(&alpha, &paint, nullptr, &offset);
+ paint.setColor(SK_ColorRED);
+ canvas->drawBitmap(bitmap, 0, -offset.fY, &paint);
+ canvas->drawBitmap(alpha, 100 + offset.fX, 0, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/not_path_gradient.cpp b/docs/examples/not_path_gradient.cpp
new file mode 100644
index 0000000..30f9f6e
--- /dev/null
+++ b/docs/examples/not_path_gradient.cpp
@@ -0,0 +1,30 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(not_path_gradient, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 60.0f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 15; ++i) {
+ SkScalar a = 0.44879895f * i;
+ SkScalar r = R + R * (i % 2);
+ path.lineTo(C + r * cos(a), C + r * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkDiscretePathEffect::Make(10.0f, 4.0f));
+ SkPoint points[2] = {SkPoint::Make(0.0f, 0.0f), SkPoint::Make(256.0f, 256.0f)};
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(10);
+ SkColor colors[2] = {SkColorSetRGB(0xEA, 0xD2, 0xAC), SkColorSetRGB(0x42, 0x81, 0xA4)};
+ paint.setShader(
+ SkGradientShader::MakeLinear(points, colors, NULL, 2, SkTileMode::kClamp, 0, NULL));
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/pathmeasure.cpp b/docs/examples/pathmeasure.cpp
new file mode 100644
index 0000000..28badd0
--- /dev/null
+++ b/docs/examples/pathmeasure.cpp
@@ -0,0 +1,16 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(pathmeasure, 256, 256, true, 0) {
+void draw(SkCanvas* canvas) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.moveTo(0, 1);
+ path.lineTo(1, 1);
+ SkPathMeasure measure(path, false);
+ SkPath result;
+ measure.getSegment(.5, 1.5, &result, true);
+ result.dump();
+}
+} // END FIDDLE
diff --git a/docs/examples/pathops.cpp b/docs/examples/pathops.cpp
new file mode 100644
index 0000000..f0c5111
--- /dev/null
+++ b/docs/examples/pathops.cpp
@@ -0,0 +1,84 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(pathops, 1000, 600, false, 0) {
+void makePaint(SkPaint * paint, SkColor color) {
+ paint->setAntiAlias(true);
+ paint->setStyle(SkPaint::kFill_Style);
+ paint->setColor(color);
+}
+
+SkColor blend(SkColor one, SkColor two) {
+ SkBitmap temp;
+ temp.allocN32Pixels(1, 1);
+ SkCanvas canvas(temp);
+ canvas.drawColor(one);
+ canvas.drawColor(two);
+ void* pixels = temp.getPixels();
+ return *(SkColor*)pixels;
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint fOnePaint;
+ SkPaint fTwoPaint;
+ SkPaint fOutlinePaint;
+ SkPaint fOpPaint[kReverseDifference_SkPathOp - kDifference_SkPathOp + 1];
+
+ const unsigned oneColor = 0xFF8080FF;
+ const unsigned twoColor = 0x807F1f1f;
+ SkColor blendColor = blend(oneColor, twoColor);
+ makePaint(&fOnePaint, oneColor);
+ makePaint(&fTwoPaint, twoColor);
+ makePaint(&fOpPaint[kDifference_SkPathOp], oneColor);
+ makePaint(&fOpPaint[kIntersect_SkPathOp], blendColor);
+ makePaint(&fOpPaint[kUnion_SkPathOp], 0xFFc0FFc0);
+ makePaint(&fOpPaint[kReverseDifference_SkPathOp], twoColor);
+ makePaint(&fOpPaint[kXOR_SkPathOp], 0xFFa0FFe0);
+ makePaint(&fOutlinePaint, 0xFF000000);
+ fOutlinePaint.setStyle(SkPaint::kStroke_Style);
+
+ SkPath one, two;
+ int yPos = 0;
+ for (int oneFill = 0; oneFill <= 1; ++oneFill) {
+ SkPathFillType oneF =
+ oneFill ? SkPathFillType::kInverseEvenOdd : SkPathFillType::kEvenOdd;
+ for (int twoFill = 0; twoFill <= 1; ++twoFill) {
+ SkPathFillType twoF =
+ twoFill ? SkPathFillType::kInverseEvenOdd : SkPathFillType::kEvenOdd;
+ one.reset();
+ one.setFillType(oneF);
+
+ one.moveTo(10, 10);
+ one.conicTo(0, 90, 50, 50, 3);
+ one.conicTo(90, 0, 90, 90, 2);
+ one.close();
+
+ two.reset();
+ two.setFillType(twoF);
+ two.addRect(40, 40, 100, 100);
+ canvas->save();
+ canvas->translate(0, SkIntToScalar(yPos));
+ canvas->clipRect(SkRect::MakeWH(110, 110), SkClipOp::kIntersect, true);
+ canvas->drawPath(one, fOnePaint);
+ canvas->drawPath(one, fOutlinePaint);
+ canvas->drawPath(two, fTwoPaint);
+ canvas->drawPath(two, fOutlinePaint);
+ canvas->restore();
+ int xPos = 150;
+ for (int op = kDifference_SkPathOp; op <= kReverseDifference_SkPathOp; ++op) {
+ SkPath result;
+ Op(one, two, (SkPathOp)op, &result);
+ canvas->save();
+ canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
+ canvas->clipRect(SkRect::MakeWH(110, 110), SkClipOp::kIntersect, true);
+ canvas->drawPath(result, fOpPaint[op]);
+ canvas->drawPath(result, fOutlinePaint);
+ canvas->restore();
+ xPos += 150;
+ }
+ yPos += 150;
+ }
+ }
+}
+
+} // END FIDDLE
diff --git a/docs/examples/persp_text_2.cpp b/docs/examples/persp_text_2.cpp
new file mode 100644
index 0000000..c12f1df
--- /dev/null
+++ b/docs/examples/persp_text_2.cpp
@@ -0,0 +1,16 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(persp_text_2, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ SkMatrix persp;
+ persp.setAll(0.9839f, 0, 0, 0.2246f, 0.6829f, 0, 0.0002352f, -0.0003844f, 1);
+ canvas->concat(persp);
+ canvas->translate(100, 0);
+ canvas->scale(375, 375);
+
+ const char text[] = "SKIA";
+ canvas->drawString(text, 0, 0, SkFont(nullptr, 0.1f), paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/picture_shader.cpp b/docs/examples/picture_shader.cpp
new file mode 100644
index 0000000..80dd0ea
--- /dev/null
+++ b/docs/examples/picture_shader.cpp
@@ -0,0 +1,60 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(picture_shader, 256, 256, false, 5) {
+static void draw_centered(
+ const char* s, const SkFont& font, SkColor color, SkPoint xy, SkCanvas* c) {
+ sk_sp<SkTextBlob> b = SkTextBlob::MakeFromString(s, font);
+ xy -= SkPoint{b->bounds().centerX(), b->bounds().centerY()};
+ SkPaint p;
+ p.setColor(color);
+ c->drawTextBlob(b.get(), xy.x(), xy.y(), p);
+}
+
+SkPoint from_polar_deg(float r, float d) {
+ float a = d * 0.017453292519943295;
+ return {r * cosf(a), r * sinf(a)};
+}
+
+void draw_wheel(SkCanvas* c) {
+ const SkScalar scale = 512;
+ SkAutoCanvasRestore autoCanvasRestore(c, true);
+ c->translate(0.5f * scale, 0.5f * scale);
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setColor(SK_ColorWHITE);
+ c->drawCircle(0.0f, 0.0f, scale * 0.475f, p);
+
+ const SkColor sweep_colors[] = {SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorCYAN,
+ SK_ColorBLUE, SK_ColorMAGENTA, SK_ColorRED};
+ SkMatrix rot;
+ rot.setRotate(90.0f);
+ p.setShader(SkGradientShader::MakeSweep(0, 0, sweep_colors, NULL,
+ SK_ARRAY_COUNT(sweep_colors), 0, &rot));
+ p.setStrokeWidth(0.05f * scale);
+ p.setStyle(SkPaint::kStroke_Style);
+ c->drawCircle(0.0f, 0.0f, 0.475f * scale, p);
+
+ SkFont f(nullptr, 0.28125f * scale);
+ draw_centered("K", f, SK_ColorBLACK, {0.0f, 0.0f}, c);
+ draw_centered("R", f, SK_ColorRED, from_polar_deg(0.3f * scale, 90), c);
+ draw_centered("G", f, SK_ColorGREEN, from_polar_deg(0.3f * scale, 210), c);
+ draw_centered("B", f, SK_ColorBLUE, from_polar_deg(0.3f * scale, 330), c);
+ draw_centered("C", f, SK_ColorCYAN, from_polar_deg(0.3f * scale, 270), c);
+ draw_centered("M", f, SK_ColorMAGENTA, from_polar_deg(0.3f * scale, 30), c);
+ draw_centered("Y", f, SK_ColorYELLOW, from_polar_deg(0.3f * scale, 150), c);
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorWHITE);
+ SkMatrix matrix;
+ matrix.setScale(0.25f, 0.25f);
+ matrix.preRotate(30.0f);
+ SkPaint paint;
+ SkPictureRecorder rec;
+ draw_wheel(rec.beginRecording(512, 512));
+ paint.setShader(rec.finishRecordingAsPicture()->makeShader(
+ SkTileMode::kRepeat, SkTileMode::kRepeat, &matrix, nullptr));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/purplestamp.cpp b/docs/examples/purplestamp.cpp
new file mode 100644
index 0000000..0fde706
--- /dev/null
+++ b/docs/examples/purplestamp.cpp
@@ -0,0 +1,57 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(purplestamp, 256, 256, false, 0) {
+// purplestamp
+
+// Whether to use a separate bitmap (with a color type) at all.
+bool drawWithRasterImage = true;
+
+// This works with either kN32_SkColorType or kAlpha_8_SkColorType.
+// Applies only if drawWithRasterImage is true.
+SkColorType colorType = kN32_SkColorType;
+
+void drawStamp(SkCanvas* canvas, int size) {
+ canvas->save();
+ canvas->clipRect(SkRect::MakeWH(size, size), SkClipOp::kIntersect, true);
+
+ canvas->clear(0x3F000000 /* translucent black */);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(SK_ColorBLACK);
+ canvas->drawRRect(
+ SkRRect::MakeOval(SkRect::MakeXYWH(size / 4, size / 4, size / 2, size / 2)), paint);
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(20);
+ canvas->drawRect(SkRect::MakeWH(size, size), paint);
+
+ canvas->restore();
+}
+
+sk_sp<SkImage> stampImage(int size) {
+ sk_sp<SkSurface> surface = SkSurface::MakeRaster(
+ SkImageInfo::Make(size, size, colorType, kPremul_SkAlphaType));
+ drawStamp(surface->getCanvas(), size);
+ return surface->makeImageSnapshot();
+}
+
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setColorFilter(SkColorFilters::Blend(0xFF7F00FF, SkBlendMode::kSrcIn));
+ paint.setFilterQuality(kMedium_SkFilterQuality);
+ paint.setAntiAlias(true);
+ canvas->rotate(30);
+ canvas->translate(60, 0);
+
+ int stampSize = 200;
+ if (drawWithRasterImage) {
+ canvas->drawImage(stampImage(stampSize), 0, 0, &paint);
+ } else {
+ canvas->saveLayer(nullptr, &paint);
+ drawStamp(canvas, stampSize);
+ canvas->restore();
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/radial_gradient_test.cpp b/docs/examples/radial_gradient_test.cpp
new file mode 100644
index 0000000..28c1a89
--- /dev/null
+++ b/docs/examples/radial_gradient_test.cpp
@@ -0,0 +1,24 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(radial_gradient_test, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+#define SIZE 121
+ SkScalar half = SIZE * 0.5f;
+ const SkColor preColor = 0xFFFF0000; // clamp color before start
+ const SkColor postColor = 0xFF0000FF; // clamp color after end
+ const SkColor color0 = 0xFF000000;
+ const SkColor color1 = 0xFF00FF00;
+
+ SkColor cs[] = {preColor, color0, color1, postColor};
+ SkScalar pos[] = {0, 0, 1, 1};
+
+ auto s = SkGradientShader::MakeRadial({half, half}, half - 10, cs, pos, 4,
+ SkTileMode::kClamp);
+
+ SkPaint p;
+ const SkRect rect = SkRect::MakeWH(SIZE, SIZE);
+ p.setShader(s);
+ canvas->drawRect(rect, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/redwhiteonblue.cpp b/docs/examples/redwhiteonblue.cpp
new file mode 100644
index 0000000..053dbed
--- /dev/null
+++ b/docs/examples/redwhiteonblue.cpp
@@ -0,0 +1,14 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(redwhiteonblue, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorBLUE);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(SK_ColorWHITE);
+ canvas->drawRect({10.5, 10.5, 120.5, 120.5}, paint);
+ paint.setColor(SK_ColorRED);
+ canvas->drawRect({120.5, 10.5, 230.5, 120.5}, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/rotations.cpp b/docs/examples/rotations.cpp
new file mode 100644
index 0000000..89e6205
--- /dev/null
+++ b/docs/examples/rotations.cpp
@@ -0,0 +1,19 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(rotations, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->translate(128, 0);
+ canvas->rotate(60);
+ SkRect rect = SkRect::MakeXYWH(0, 0, 200, 100);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(0xff4285F4);
+ canvas->drawRect(rect, paint);
+
+ canvas->rotate(SkIntToScalar(20));
+ paint.setColor(0xffDB4437);
+ canvas->drawRect(rect, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/setimagefilter.cpp b/docs/examples/setimagefilter.cpp
new file mode 100644
index 0000000..79fb91a
--- /dev/null
+++ b/docs/examples/setimagefilter.cpp
@@ -0,0 +1,20 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(setimagefilter, 256, 100, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(100, 100);
+ SkCanvas offscreen(bitmap);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(SK_ColorWHITE);
+ SkFont font(nullptr, 96);
+ offscreen.clear(0);
+ offscreen.drawString("e", 20, 70, font, paint);
+ paint.setImageFilter(SkLightingImageFilter::MakePointLitDiffuse(
+ SkPoint3::Make(80, 100, 10), SK_ColorWHITE, 1, 2, nullptr, nullptr));
+ canvas->drawBitmap(bitmap, 0, 0, &paint);
+}
+
+} // END FIDDLE
diff --git a/docs/examples/shader.cpp b/docs/examples/shader.cpp
new file mode 100644
index 0000000..4d0a0b9
--- /dev/null
+++ b/docs/examples/shader.cpp
@@ -0,0 +1,28 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(shader, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 60.0f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 15; ++i) {
+ SkScalar a = 0.44879895f * i;
+ SkScalar r = R + R * (i % 2);
+ path.lineTo(C + r * cos(a), C + r * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkDiscretePathEffect::Make(10.0f, 4.0f));
+ SkPoint points[2] = {SkPoint::Make(0.0f, 0.0f), SkPoint::Make(256.0f, 256.0f)};
+ SkColor colors[2] = {SkColorSetRGB(66, 133, 244), SkColorSetRGB(15, 157, 88)};
+ paint.setShader(
+ SkGradientShader::MakeLinear(points, colors, NULL, 2, SkTileMode::kClamp, 0, NULL));
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/shader_alphaimage.cpp b/docs/examples/shader_alphaimage.cpp
new file mode 100644
index 0000000..ee83df2
--- /dev/null
+++ b/docs/examples/shader_alphaimage.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(shader_alphaimage, 256, 256, false, 0) {
+sk_sp<SkImage> alpha_image() {
+ auto s = SkSurface::MakeRaster(SkImageInfo::MakeA8(128, 128));
+ s->getCanvas()->clear(SkColorSetARGB(0xF0, 0x00, 0x00, 0x00));
+ return s->makeImageSnapshot();
+}
+sk_sp<SkShader> linear_gradient() {
+ SkPoint gpts[2] = {{0, 0}, {256, 256}};
+ SkColor gc[6] = {SK_ColorCYAN, SK_ColorBLUE, SK_ColorMAGENTA,
+ SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN};
+ return SkGradientShader::MakeLinear(gpts, gc, nullptr, 6, SkTileMode::kClamp);
+}
+
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorLTGRAY);
+ SkPaint p;
+ p.setShader(linear_gradient());
+ auto i = alpha_image();
+ canvas->drawImage(i.get(), 128, 0, &p);
+ canvas->drawRect({0, 128, 128, 256}, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/skbug6031.cpp b/docs/examples/skbug6031.cpp
new file mode 100644
index 0000000..2f8779d
--- /dev/null
+++ b/docs/examples/skbug6031.cpp
@@ -0,0 +1,32 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skbug6031, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ constexpr float kW = 512;
+ constexpr float kH = 512;
+
+ SkPaint paint;
+ static constexpr SkClipOp replaceClipOp = static_cast<SkClipOp>(5);
+
+ canvas->clipRect(SkRect{0, 0, 2 * kW, 2 * kH}, replaceClipOp);
+ paint.setColor(SkColorSetARGB(0, 0, 0, 0));
+ canvas->drawPaint(paint);
+
+ canvas->clipRect(SkRect{0, 0, kW, kH}, replaceClipOp);
+ paint.setColor(SkColorSetARGB(255, 127, 0, 0));
+ canvas->drawPaint(paint);
+
+ canvas->clipRect(SkRect{0, kH, kW, 3 * kH}, replaceClipOp);
+ paint.setColor(SkColorSetARGB(255, 0, 127, 0));
+ canvas->drawPaint(paint);
+
+ canvas->clipRect(SkRect{kW, 0, 3 * kW, kH}, replaceClipOp);
+ paint.setColor(SkColorSetARGB(255, 0, 0, 127));
+ canvas->drawPaint(paint);
+
+ canvas->clipRect(SkRect{kW, kH, 3 * kW, 3 * kH}, replaceClipOp);
+ paint.setColor(SkColorSetARGB(255, 127, 127, 0));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skbug_237_drawImageRect.cpp b/docs/examples/skbug_237_drawImageRect.cpp
new file mode 100644
index 0000000..bcf1320
--- /dev/null
+++ b/docs/examples/skbug_237_drawImageRect.cpp
@@ -0,0 +1,12 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skbug_237_drawImageRect, 256, 256, false, 6) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 20.0f, false));
+ canvas->clear(0xFF88FF88);
+ canvas->drawImageRect(image, SkRect{16, 16, 48, 48}, {64, 64, 192, 192}, &paint,
+ SkCanvas::kFast_SrcRectConstraint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skbug_237_drawImage_with_blur.cpp b/docs/examples/skbug_237_drawImage_with_blur.cpp
new file mode 100644
index 0000000..9800b2f
--- /dev/null
+++ b/docs/examples/skbug_237_drawImage_with_blur.cpp
@@ -0,0 +1,13 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skbug_237_drawImage_with_blur, 256, 256, false, 6) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5.0f, false));
+ canvas->clear(0xFF88FF88);
+ canvas->scale(4, 4);
+ auto subset = image->makeSubset({16, 16, 48, 48});
+ canvas->drawImage(subset, 16, 16, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skbug_5648.cpp b/docs/examples/skbug_5648.cpp
new file mode 100644
index 0000000..d298469
--- /dev/null
+++ b/docs/examples/skbug_5648.cpp
@@ -0,0 +1,13 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skbug_5648, 256, 256, true, 4) {
+// skbug_5648
+void draw(SkCanvas*) {
+ SkBitmap bitmap;
+ source.extractSubset(&bitmap, {0, 0, source.width() - 1, source.height() - 1});
+ auto img0 = SkImage::MakeFromBitmap(bitmap);
+ auto img1 = SkImage::MakeFromBitmap(bitmap);
+ SkDebugf("%u\n%u\n", img0->uniqueID(), img1->uniqueID());
+}
+} // END FIDDLE
diff --git a/docs/examples/skbug_633528.cpp b/docs/examples/skbug_633528.cpp
new file mode 100644
index 0000000..326672d
--- /dev/null
+++ b/docs/examples/skbug_633528.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skbug_633528, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ static const char imageData[] =
+ "\211PNG\r\n\32\n\0\0\0\rIHDR\0\0\0\202\0\0\0\202\2\3\0\0\0\367m\370"
+ "n\0\0\0\tPLTE\0\1\0\0\377\377\375\377\374\301\233\213\345\0\0\0\tp"
+ "HYs\0\0\13\23\0\0\13\23\1\0\232\234\30\0\0\0\7tIME\7\340\10\2\22\2"
+ " V\23\7<\0\0\0\341IDATX\303\205\3301a\3\1\20\3\301'\21\10)\34\24&\21"
+ "h\202\240B\207\322\14<[\17\202}\36\366\363\377\275\367\363K\361\242"
+ "\370\263\10E)Fq\26\241(\305(\316\"\24\245\30\305Y\204\242\24\2438\213"
+ "P\224b\24g\21\212R\214\342,BQ\212Q\234E(J1\212\263\10E)Fq\26\241(\305"
+ "(\316\"\24\245\30\305Y\204\242\24\2438\213P\224b\24g\21\212R\214\342"
+ ",BQ\212Q\234E(J1\212\263\10E)Fq\26\241(\305(\316\"\24\245\30\305Y\204"
+ "\242\24\2438\213P\224b\24g\21\212R\214\342,BQ\212Q\234E(J1\212\263"
+ "\10E)Fq\26\241(\305(\316\"\24\245\30\305Y\204\242\24\2438\213P\224"
+ "b\24g\21\212R\214\342,BQ\212Q\334\333\203\344\3v\211\352J5\271\206"
+ "*\0\0\0\0IEND\256B`\202";
+ auto i = SkImage::MakeFromEncoded(SkData::MakeWithoutCopy(imageData, 343));
+ canvas->scale(0.99f, 1.01f);
+ canvas->clipRect(SkRect::MakeXYWH(64, 64, 128, 128));
+ canvas->drawImage(i, 63, 63);
+}
+} // END FIDDLE
diff --git a/docs/examples/skcanvas_paint.cpp b/docs/examples/skcanvas_paint.cpp
new file mode 100644
index 0000000..72e4bc2
--- /dev/null
+++ b/docs/examples/skcanvas_paint.cpp
@@ -0,0 +1,43 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skcanvas_paint, 256, 256, false, 5) {
+void draw(SkCanvas* canvas) {
+ canvas->drawColor(SK_ColorWHITE);
+
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(4);
+ paint.setColor(SK_ColorRED);
+
+ SkRect rect = SkRect::MakeXYWH(50, 50, 40, 60);
+ canvas->drawRect(rect, paint);
+
+ SkRRect oval;
+ oval.setOval(rect);
+ oval.offset(40, 60);
+ paint.setColor(SK_ColorBLUE);
+ canvas->drawRRect(oval, paint);
+
+ paint.setColor(SK_ColorCYAN);
+ canvas->drawCircle(180, 50, 25, paint);
+
+ rect.offset(80, 0);
+ paint.setColor(SK_ColorYELLOW);
+ canvas->drawRoundRect(rect, 10, 10, paint);
+
+ SkPath path;
+ path.cubicTo(768, 0, -512, 256, 256, 256);
+ paint.setColor(SK_ColorGREEN);
+ canvas->drawPath(path, paint);
+
+ canvas->drawImage(image, 128, 128, &paint);
+
+ SkRect rect2 = SkRect::MakeXYWH(0, 0, 40, 60);
+ canvas->drawImageRect(image, rect2, &paint);
+
+ SkPaint paint2;
+ auto text = SkTextBlob::MakeFromString("Hello, Skia!", SkFont(nullptr, 18));
+ canvas->drawTextBlob(text.get(), 50, 25, paint2);
+}
+} // END FIDDLE
diff --git a/docs/examples/skcanvas_square.cpp b/docs/examples/skcanvas_square.cpp
new file mode 100644
index 0000000..fc342ec
--- /dev/null
+++ b/docs/examples/skcanvas_square.cpp
@@ -0,0 +1,15 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skcanvas_square, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->save();
+ canvas->translate(SkIntToScalar(128), SkIntToScalar(128));
+ canvas->rotate(SkIntToScalar(45));
+ SkRect rect = SkRect::MakeXYWH(-90.5f, -90.5f, 181.0f, 181.0f);
+ SkPaint paint;
+ paint.setColor(SK_ColorBLUE);
+ canvas->drawRect(rect, paint);
+ canvas->restore();
+}
+} // END FIDDLE
diff --git a/docs/examples/skcanvas_star.cpp b/docs/examples/skcanvas_star.cpp
new file mode 100644
index 0000000..4f5a75b
--- /dev/null
+++ b/docs/examples/skcanvas_star.cpp
@@ -0,0 +1,22 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skcanvas_star, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ const SkScalar scale = 256.0f;
+ const SkScalar R = 0.45f * scale;
+ const SkScalar TAU = 6.2831853f;
+ SkPath path;
+ path.moveTo(R, 0.0f);
+ for (int i = 1; i < 7; ++i) {
+ SkScalar theta = 3 * i * TAU / 7;
+ path.lineTo(R * cos(theta), R * sin(theta));
+ }
+ path.close();
+ SkPaint p;
+ p.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ canvas->translate(0.5f * scale, 0.5f * scale);
+ canvas->drawPath(path, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_2pt.cpp b/docs/examples/skpaint_2pt.cpp
new file mode 100644
index 0000000..0e64ae8
--- /dev/null
+++ b/docs/examples/skpaint_2pt.cpp
@@ -0,0 +1,13 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_2pt, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
+ SkPaint paint;
+ paint.setShader(SkGradientShader::MakeTwoPointConical(
+ SkPoint::Make(128.0f, 128.0f), 128.0f, SkPoint::Make(128.0f, 16.0f), 16.0f, colors,
+ nullptr, 2, SkTileMode::kClamp, 0, nullptr));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_bitmap_shader.cpp b/docs/examples/skpaint_bitmap_shader.cpp
new file mode 100644
index 0000000..b931aad
--- /dev/null
+++ b/docs/examples/skpaint_bitmap_shader.cpp
@@ -0,0 +1,14 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_bitmap_shader, 256, 256, false, 5) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorWHITE);
+ SkMatrix matrix;
+ matrix.setScale(0.75f, 0.75f);
+ matrix.preRotate(30.0f);
+ SkPaint paint;
+ paint.setShader(image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &matrix));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_blur_mask_filter.cpp b/docs/examples/skpaint_blur_mask_filter.cpp
new file mode 100644
index 0000000..efc2c4f
--- /dev/null
+++ b/docs/examples/skpaint_blur_mask_filter.cpp
@@ -0,0 +1,12 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_blur_mask_filter, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->drawColor(SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF));
+ SkPaint paint;
+ paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5.0f));
+ sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("Skia", SkFont(nullptr, 120));
+ canvas->drawTextBlob(blob.get(), 0, 160, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_blur_mask_filter_2.cpp b/docs/examples/skpaint_blur_mask_filter_2.cpp
new file mode 100644
index 0000000..1686928
--- /dev/null
+++ b/docs/examples/skpaint_blur_mask_filter_2.cpp
@@ -0,0 +1,34 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_blur_mask_filter_2, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ const SkScalar blurSigma = 3.4f;
+ const SkColor blurColor = SkColorSetRGB(96, 96, 0);
+ const uint8_t blurAlpha = 127;
+ const SkScalar xDrop = 5.0f;
+ const SkScalar yDrop = 5.0f;
+
+ const char text[] = "Skia";
+ const SkScalar x = 0.0f;
+ const SkScalar y = 160.0f;
+
+ canvas->drawColor(SK_ColorWHITE);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ SkPaint blur(paint);
+ blur.setColor(blurColor);
+ blur.setAlpha(blurAlpha);
+ blur.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, blurSigma, false));
+
+ SkFont font(nullptr, 120);
+
+ // Draw once with drop shadow blur;
+ canvas->drawString(text, x + xDrop, y + yDrop, font, blur);
+
+ // Overdraw with with no blur mask
+ canvas->drawString(text, x, y, font, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_color_table_filter.cpp b/docs/examples/skpaint_color_table_filter.cpp
new file mode 100644
index 0000000..6df1d88
--- /dev/null
+++ b/docs/examples/skpaint_color_table_filter.cpp
@@ -0,0 +1,16 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_color_table_filter, 256, 256, false, 3) {
+void draw(SkCanvas* canvas) {
+ canvas->scale(0.5, 0.5);
+ uint8_t ct[256];
+ for (int i = 0; i < 256; ++i) {
+ int x = (i - 96) * 255 / 64;
+ ct[i] = x < 0 ? 0 : x > 255 ? 255 : x;
+ }
+ SkPaint paint;
+ paint.setColorFilter(SkTableColorFilter::MakeARGB(nullptr, ct, ct, ct));
+ canvas->drawImage(image, 0, 0, &paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_compose.cpp b/docs/examples/skpaint_compose.cpp
new file mode 100644
index 0000000..88192d3
--- /dev/null
+++ b/docs/examples/skpaint_compose.cpp
@@ -0,0 +1,15 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_compose, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
+ SkPaint paint;
+ paint.setShader(SkShaders::Blend(
+ SkBlendMode::kDifference,
+ SkGradientShader::MakeRadial(SkPoint::Make(128.0f, 128.0f), 180.0f, colors, NULL, 2,
+ SkTileMode::kClamp, 0, NULL),
+ SkPerlinNoiseShader::MakeTurbulence(0.025f, 0.025f, 2, 0.0f, NULL)));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_compose_path_effect.cpp b/docs/examples/skpaint_compose_path_effect.cpp
new file mode 100644
index 0000000..b7c12b8
--- /dev/null
+++ b/docs/examples/skpaint_compose_path_effect.cpp
@@ -0,0 +1,29 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_compose_path_effect, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ const SkScalar intervals[] = {10.0f, 5.0f, 2.0f, 5.0f};
+ size_t count = sizeof(intervals) / sizeof(intervals[0]);
+ SkPaint paint;
+ paint.setPathEffect(
+ SkPathEffect::MakeCompose(SkDashPathEffect::Make(intervals, count, 0.0f),
+ SkDiscretePathEffect::Make(10.0f, 4.0f)));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_compose_shader.cpp b/docs/examples/skpaint_compose_shader.cpp
new file mode 100644
index 0000000..671d103
--- /dev/null
+++ b/docs/examples/skpaint_compose_shader.cpp
@@ -0,0 +1,16 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_compose_shader, 256, 256, false, 0) {
+// skpaint_compose_shader
+void draw(SkCanvas* canvas) {
+ SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
+ SkPaint paint;
+ paint.setShader(SkShaders::Blend(
+ SkBlendMode::kDifference,
+ SkGradientShader::MakeRadial(SkPoint::Make(128.0f, 128.0f), 180.0f, colors, nullptr,
+ 2, SkTileMode::kClamp, 0, nullptr),
+ SkPerlinNoiseShader::MakeTurbulence(0.025f, 0.025f, 2, 0.0f, nullptr)));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_corner_path_effects.cpp b/docs/examples/skpaint_corner_path_effects.cpp
new file mode 100644
index 0000000..d4ef126
--- /dev/null
+++ b/docs/examples/skpaint_corner_path_effects.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_corner_path_effects, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 7; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ path.close();
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkCornerPathEffect::Make(32.0f));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_dash_path_effect.cpp b/docs/examples/skpaint_dash_path_effect.cpp
new file mode 100644
index 0000000..89f05a2
--- /dev/null
+++ b/docs/examples/skpaint_dash_path_effect.cpp
@@ -0,0 +1,27 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_dash_path_effect, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ const SkScalar intervals[] = {10.0f, 5.0f, 2.0f, 5.0f};
+ size_t count = sizeof(intervals) / sizeof(intervals[0]);
+ SkPaint paint;
+ paint.setPathEffect(SkDashPathEffect::Make(intervals, count, 0.0f));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_discrete_path_effect.cpp b/docs/examples/skpaint_discrete_path_effect.cpp
new file mode 100644
index 0000000..f4cabb8
--- /dev/null
+++ b/docs/examples/skpaint_discrete_path_effect.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_discrete_path_effect, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkDiscretePathEffect::Make(10.0f, 4.0f));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_line_2d_path_effect.cpp b/docs/examples/skpaint_line_2d_path_effect.cpp
new file mode 100644
index 0000000..84d0f5a
--- /dev/null
+++ b/docs/examples/skpaint_line_2d_path_effect.cpp
@@ -0,0 +1,17 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_line_2d_path_effect, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ SkMatrix lattice;
+ lattice.setScale(8.0f, 8.0f);
+ lattice.preRotate(30.0f);
+ paint.setPathEffect(SkLine2DPathEffect::Make(0.0f, lattice));
+ paint.setAntiAlias(true);
+ SkRect bounds = SkRect::MakeWH(256, 256);
+ bounds.outset(8.0f, 8.0f);
+ canvas->clear(SK_ColorWHITE);
+ canvas->drawRect(bounds, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_matrix_color_filter.cpp b/docs/examples/skpaint_matrix_color_filter.cpp
new file mode 100644
index 0000000..185c010
--- /dev/null
+++ b/docs/examples/skpaint_matrix_color_filter.cpp
@@ -0,0 +1,26 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_matrix_color_filter, 256, 128, false, 3) {
+void f(SkCanvas* c, SkScalar x, SkScalar y, SkScalar colorMatrix[20]) {
+ SkPaint paint;
+ paint.setColorFilter(SkColorFilters::Matrix(colorMatrix));
+ c->drawImage(image, x, y, &paint);
+}
+void draw(SkCanvas* c) {
+ c->scale(0.25, 0.25);
+ SkScalar colorMatrix1[20] = {
+ 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 1, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0};
+ f(c, 0, 0, colorMatrix1);
+
+ SkScalar grayscale[20] = {
+ 0.21f, 0.72f, 0.07f, 0.0f, 0.0f,
+ 0.21f, 0.72f, 0.07f, 0.0f, 0.0f,
+ 0.21f, 0.72f, 0.07f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
+ f(c, 512, 0, grayscale);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_mix.cpp b/docs/examples/skpaint_mix.cpp
new file mode 100644
index 0000000..5c8dc94
--- /dev/null
+++ b/docs/examples/skpaint_mix.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_mix, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint fillPaint;
+ SkPaint strokePaint;
+ strokePaint.setStyle(SkPaint::kStroke_Style);
+ strokePaint.setStrokeWidth(3.0f);
+
+ canvas->drawRect(SkRect::MakeXYWH(10, 10, 60, 20), fillPaint);
+ canvas->drawRect(SkRect::MakeXYWH(80, 10, 60, 20), strokePaint);
+
+ strokePaint.setStrokeWidth(5.0f);
+ canvas->drawOval(SkRect::MakeXYWH(150, 10, 60, 20), strokePaint);
+
+ sk_sp<SkTextBlob> blob = SkTextBlob::MakeFromString("SKIA", SkFont(nullptr, 80));
+
+ fillPaint.setColor(SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00));
+ canvas->drawTextBlob(blob.get(), 20, 120, fillPaint);
+
+ fillPaint.setColor(SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF));
+ canvas->drawTextBlob(blob.get(), 20, 220, fillPaint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_path_1d_path_effect.cpp b/docs/examples/skpaint_path_1d_path_effect.cpp
new file mode 100644
index 0000000..b802852
--- /dev/null
+++ b/docs/examples/skpaint_path_1d_path_effect.cpp
@@ -0,0 +1,15 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_path_1d_path_effect, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ SkPath path;
+ path.addOval(SkRect::MakeWH(16.0f, 6.0f));
+ paint.setPathEffect(
+ SkPath1DPathEffect::Make(path, 32.0f, 0.0f, SkPath1DPathEffect::kRotate_Style));
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ canvas->drawCircle(128.0f, 128.0f, 122.0f, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_path_2d_path_effect.cpp b/docs/examples/skpaint_path_2d_path_effect.cpp
new file mode 100644
index 0000000..de2bb9a
--- /dev/null
+++ b/docs/examples/skpaint_path_2d_path_effect.cpp
@@ -0,0 +1,23 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_path_2d_path_effect, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkScalar scale = 10.0f;
+ SkPath path;
+ static const int8_t pts[] = {2, 2, 1, 3, 0, 3, 2, 1, 3, 1, 4, 0, 4, 1,
+ 5, 1, 4, 2, 4, 3, 2, 5, 2, 4, 3, 3, 2, 3};
+ path.moveTo(2 * scale, 3 * scale);
+ for (size_t i = 0; i < sizeof(pts) / sizeof(pts[0]); i += 2) {
+ path.lineTo(pts[i] * scale, pts[i + 1] * scale);
+ }
+ path.close();
+ SkMatrix matrix = SkMatrix::MakeScale(4 * scale);
+ SkPaint paint;
+ paint.setPathEffect(SkPath2DPathEffect::Make(matrix, path));
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkRect bounds{-4 * scale, -4 * scale, 256, 256};
+ canvas->drawRect(bounds, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_perlin.cpp b/docs/examples/skpaint_perlin.cpp
new file mode 100644
index 0000000..e390841
--- /dev/null
+++ b/docs/examples/skpaint_perlin.cpp
@@ -0,0 +1,11 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_perlin, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorWHITE);
+ SkPaint paint;
+ paint.setShader(SkPerlinNoiseShader::MakeFractalNoise(0.05f, 0.05f, 4, 0.0f, nullptr));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_radial.cpp b/docs/examples/skpaint_radial.cpp
new file mode 100644
index 0000000..6d86393
--- /dev/null
+++ b/docs/examples/skpaint_radial.cpp
@@ -0,0 +1,12 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_radial, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
+ SkPaint paint;
+ paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(128.0f, 128.0f), 180.0f, colors,
+ nullptr, 2, SkTileMode::kClamp, 0, nullptr));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_shader.cpp b/docs/examples/skpaint_shader.cpp
new file mode 100644
index 0000000..edc6aab
--- /dev/null
+++ b/docs/examples/skpaint_shader.cpp
@@ -0,0 +1,13 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_shader, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPoint points[2] = {SkPoint::Make(0.0f, 0.0f), SkPoint::Make(256.0f, 256.0f)};
+ SkColor colors[2] = {SK_ColorBLUE, SK_ColorYELLOW};
+ SkPaint paint;
+ paint.setShader(SkGradientShader::MakeLinear(points, colors, nullptr, 2, SkTileMode::kClamp,
+ 0, nullptr));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_skia.cpp b/docs/examples/skpaint_skia.cpp
new file mode 100644
index 0000000..3e95b4f
--- /dev/null
+++ b/docs/examples/skpaint_skia.cpp
@@ -0,0 +1,32 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_skia, 256, 256, false, 0) {
+// https://fiddle.skia.org/c/@skpaint_skia
+
+void draw(SkCanvas* canvas) {
+ SkPaint paint1, paint2, paint3;
+
+ paint1.setAntiAlias(true);
+ paint1.setColor(SkColorSetRGB(255, 0, 0));
+ paint1.setStyle(SkPaint::kFill_Style);
+
+ paint2.setAntiAlias(true);
+ paint2.setColor(SkColorSetRGB(0, 136, 0));
+ paint2.setStyle(SkPaint::kStroke_Style);
+ paint2.setStrokeWidth(SkIntToScalar(3));
+
+ paint3.setAntiAlias(true);
+ paint3.setColor(SkColorSetRGB(136, 136, 136));
+
+ sk_sp<SkTextBlob> blob1 =
+ SkTextBlob::MakeFromString("Skia!", SkFont(nullptr, 64.0f, 1.0f, 0.0f));
+ sk_sp<SkTextBlob> blob2 =
+ SkTextBlob::MakeFromString("Skia!", SkFont(nullptr, 64.0f, 1.5f, 0.0f));
+
+ canvas->clear(SK_ColorWHITE);
+ canvas->drawTextBlob(blob1.get(), 20.0f, 64.0f, paint1);
+ canvas->drawTextBlob(blob1.get(), 20.0f, 144.0f, paint2);
+ canvas->drawTextBlob(blob2.get(), 20.0f, 224.0f, paint3);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_sum_path_effect.cpp b/docs/examples/skpaint_sum_path_effect.cpp
new file mode 100644
index 0000000..f507b2e
--- /dev/null
+++ b/docs/examples/skpaint_sum_path_effect.cpp
@@ -0,0 +1,26 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_sum_path_effect, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkPathEffect::MakeSum(SkDiscretePathEffect::Make(10.0f, 4.0f),
+ SkDiscretePathEffect::Make(10.0f, 4.0f, 1245u)));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_sweep.cpp b/docs/examples/skpaint_sweep.cpp
new file mode 100644
index 0000000..3864488
--- /dev/null
+++ b/docs/examples/skpaint_sweep.cpp
@@ -0,0 +1,12 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_sweep, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkColor colors[4] = {SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW, SK_ColorCYAN};
+ SkPaint paint;
+ paint.setShader(
+ SkGradientShader::MakeSweep(128.0f, 128.0f, colors, nullptr, 4, 0, nullptr));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_turb.cpp b/docs/examples/skpaint_turb.cpp
new file mode 100644
index 0000000..9557959
--- /dev/null
+++ b/docs/examples/skpaint_turb.cpp
@@ -0,0 +1,11 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_turb, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorWHITE);
+ SkPaint paint;
+ paint.setShader(SkPerlinNoiseShader::MakeTurbulence(0.05f, 0.05f, 4, 0.0f, nullptr));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/skpaint_xfer.cpp b/docs/examples/skpaint_xfer.cpp
new file mode 100644
index 0000000..01f26ba
--- /dev/null
+++ b/docs/examples/skpaint_xfer.cpp
@@ -0,0 +1,86 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(skpaint_xfer, 576, 640, false, 0) {
+static void draw_utf8_string(SkCanvas* c, const char* t, SkScalar x, SkScalar y,
+ const SkFont& f, const SkPaint& p) {
+ c->drawTextBlob(SkTextBlob::MakeFromString(t, f).get(), x, y, p);
+}
+
+void draw(SkCanvas* canvas) {
+ SkBlendMode modes[] = {
+ SkBlendMode::kClear,
+ SkBlendMode::kSrc,
+ SkBlendMode::kDst,
+ SkBlendMode::kSrcOver,
+ SkBlendMode::kDstOver,
+ SkBlendMode::kSrcIn,
+ SkBlendMode::kDstIn,
+ SkBlendMode::kSrcOut,
+ SkBlendMode::kDstOut,
+ SkBlendMode::kSrcATop,
+ SkBlendMode::kDstATop,
+ SkBlendMode::kXor,
+ SkBlendMode::kPlus,
+ SkBlendMode::kModulate,
+ SkBlendMode::kScreen,
+ SkBlendMode::kOverlay,
+ SkBlendMode::kDarken,
+ SkBlendMode::kLighten,
+ SkBlendMode::kColorDodge,
+ SkBlendMode::kColorBurn,
+ SkBlendMode::kHardLight,
+ SkBlendMode::kSoftLight,
+ SkBlendMode::kDifference,
+ SkBlendMode::kExclusion,
+ SkBlendMode::kMultiply,
+ SkBlendMode::kHue,
+ SkBlendMode::kSaturation,
+ SkBlendMode::kColor,
+ SkBlendMode::kLuminosity,
+ };
+ SkRect rect = SkRect::MakeWH(64.0f, 64.0f);
+ SkPaint stroke, src, dst;
+ stroke.setStyle(SkPaint::kStroke_Style);
+ SkFont font(nullptr, 24);
+ SkPoint srcPoints[2] = {
+ SkPoint::Make(0.0f, 0.0f),
+ SkPoint::Make(64.0f, 0.0f)
+ };
+ SkColor srcColors[2] = {
+ SK_ColorMAGENTA & 0x00FFFFFF,
+ SK_ColorMAGENTA};
+ src.setShader(SkGradientShader::MakeLinear(
+ srcPoints, srcColors, nullptr, 2,
+ SkTileMode::kClamp, 0, nullptr));
+
+ SkPoint dstPoints[2] = {
+ SkPoint::Make(0.0f, 0.0f),
+ SkPoint::Make(0.0f, 64.0f)
+ };
+ SkColor dstColors[2] = {
+ SK_ColorCYAN & 0x00FFFFFF,
+ SK_ColorCYAN};
+ dst.setShader(SkGradientShader::MakeLinear(
+ dstPoints, dstColors, nullptr, 2,
+ SkTileMode::kClamp, 0, nullptr));
+ canvas->clear(SK_ColorWHITE);
+ size_t N = sizeof(modes) / sizeof(modes[0]);
+ size_t K = (N - 1) / 3 + 1;
+ SkASSERT(K * 64 == 640); // tall enough
+ for (size_t i = 0; i < N; ++i) {
+ SkAutoCanvasRestore autoCanvasRestore(canvas, true);
+ canvas->translate(192.0f * (i / K), 64.0f * (i % K));
+ const char* desc = SkBlendMode_Name(modes[i]);
+ draw_utf8_string(canvas, desc, 68.0f, 30.0f, font, SkPaint());
+ canvas->clipRect(SkRect::MakeWH(64.0f, 64.0f));
+ canvas->drawColor(SK_ColorLTGRAY);
+ (void)canvas->saveLayer(nullptr, nullptr);
+ canvas->clear(SK_ColorTRANSPARENT);
+ canvas->drawPaint(dst);
+ src.setBlendMode(modes[i]);
+ canvas->drawPaint(src);
+ canvas->drawRect(rect, stroke);
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/star.cpp b/docs/examples/star.cpp
new file mode 100644
index 0000000..1f86170
--- /dev/null
+++ b/docs/examples/star.cpp
@@ -0,0 +1,26 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(star, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ paint.setColor(0xff4281A4);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/star2.cpp b/docs/examples/star2.cpp
new file mode 100644
index 0000000..54f2501
--- /dev/null
+++ b/docs/examples/star2.cpp
@@ -0,0 +1,26 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(star2, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ paint.setColor(0xff4281A4);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/stroke_closed_degenerate_path.cpp b/docs/examples/stroke_closed_degenerate_path.cpp
new file mode 100644
index 0000000..807a53f
--- /dev/null
+++ b/docs/examples/stroke_closed_degenerate_path.cpp
@@ -0,0 +1,25 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(stroke_closed_degenerate_path, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPath path;
+ path.addRect({50.f, 50.f, 50.f, 50.f});
+
+ SkPaint joinStroke;
+ joinStroke.setColor(SK_ColorGREEN);
+ joinStroke.setStrokeWidth(10.f);
+ joinStroke.setStyle(SkPaint::kStroke_Style);
+ joinStroke.setStrokeJoin(SkPaint::kRound_Join);
+ canvas->drawPath(path, joinStroke);
+
+ canvas->translate(100.f, 0);
+
+ SkPaint capStroke;
+ capStroke.setColor(SK_ColorRED);
+ capStroke.setStrokeWidth(10.f);
+ capStroke.setStyle(SkPaint::kStroke_Style);
+ capStroke.setStrokeCap(SkPaint::kRound_Cap);
+ canvas->drawPath(path, capStroke);
+}
+} // END FIDDLE
diff --git a/docs/examples/strokerect_gm.cpp b/docs/examples/strokerect_gm.cpp
new file mode 100644
index 0000000..604ac6a
--- /dev/null
+++ b/docs/examples/strokerect_gm.cpp
@@ -0,0 +1,65 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(strokerect_gm, 1400, 740, false, 0) {
+void draw(SkCanvas* canvas) {
+ constexpr SkScalar kStrokeWidth = 20;
+ constexpr SkPaint::Join gJoins[] = {SkPaint::kMiter_Join, SkPaint::kRound_Join,
+ SkPaint::kBevel_Join};
+ constexpr SkScalar W = 80;
+ constexpr SkScalar H = 80;
+ constexpr SkRect gRects[] = {
+ {0, 0, W, H},
+ {W, 0, 0, H},
+ {0, H, W, 0},
+ {0, 0, kStrokeWidth, H},
+ {0, 0, W, kStrokeWidth},
+ {0, 0, kStrokeWidth / 2, kStrokeWidth / 2},
+ {0, 0, W, 0},
+ {0, 0, 0, H},
+ {0, 0, 0, 0},
+ {0, 0, W, FLT_EPSILON},
+ {0, 0, FLT_EPSILON, H},
+ {0, 0, FLT_EPSILON, FLT_EPSILON},
+ };
+ canvas->translate(kStrokeWidth * 3 / 2, kStrokeWidth * 3 / 2);
+ for (int doFill = 0; doFill <= 1; ++doFill) {
+ SkPaint::Style style = doFill ? SkPaint::kStrokeAndFill_Style : SkPaint::kStroke_Style;
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gJoins); ++i) {
+ SkPaint::Join join = gJoins[i];
+ for (size_t j = 0; j < SK_ARRAY_COUNT(gRects); ++j) {
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->translate(
+ j * (W + 2 * kStrokeWidth),
+ (i + doFill * SK_ARRAY_COUNT(gJoins)) * (H + 2 * kStrokeWidth));
+ const SkRect& rect = gRects[j];
+
+ SkPath path, fillPath;
+ path.addRect(rect);
+ SkPaint paint;
+
+ paint.setStrokeWidth(kStrokeWidth);
+ paint.setStyle(style);
+ paint.setStrokeJoin(join);
+ paint.getFillPath(path, &fillPath);
+
+ paint.setAntiAlias(true);
+ paint.setColor(0xFF8C8A8C);
+ canvas->drawRect(rect, paint);
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(0);
+ paint.setColor(SK_ColorRED);
+ canvas->drawPath(fillPath, paint);
+
+ paint.setStrokeWidth(3);
+ paint.setStrokeJoin(SkPaint::kMiter_Join);
+ int n = fillPath.countPoints();
+ SkAutoTArray<SkPoint> points(n);
+ fillPath.getPoints(points.get(), n);
+ canvas->drawPoints(SkCanvas::kPoints_PointMode, n, points.get(), paint);
+ }
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/subset_example.cpp b/docs/examples/subset_example.cpp
new file mode 100644
index 0000000..52cc43c
--- /dev/null
+++ b/docs/examples/subset_example.cpp
@@ -0,0 +1,28 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(subset_example, 512, 512, false, 3) {
+void draw(SkCanvas* canvas) {
+ canvas->drawColor(SK_ColorWHITE);
+ const int N = 8;
+ int shuffle[N * N];
+ for (int i = 0; i < (N * N); ++i) {
+ shuffle[i] = i;
+ }
+ srand(0);
+ for (int i = 0; i < (N * N); ++i) {
+ std::swap(shuffle[i], shuffle[rand() % (N * N - i) + i]);
+ }
+ int w = (source.width() - 1) / N + 1;
+ int h = (source.height() - 1) / N + 1;
+ for (int i = 0; i < N; ++i) {
+ for (int j = 0; j < N; ++j) {
+ int x = shuffle[(N * i) + j] % N;
+ int y = shuffle[(N * i) + j] / N;
+ SkBitmap subset;
+ source.extractSubset(&subset, SkIRect::MakeXYWH(w * x, h * y, w, h));
+ canvas->drawBitmap(subset, w * i, h * j);
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/sum_path_effect.cpp b/docs/examples/sum_path_effect.cpp
new file mode 100644
index 0000000..4c5e35d
--- /dev/null
+++ b/docs/examples/sum_path_effect.cpp
@@ -0,0 +1,27 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(sum_path_effect, 256, 256, false, 0) {
+SkPath star() {
+ const SkScalar R = 115.2f, C = 128.0f;
+ SkPath path;
+ path.moveTo(C + R, C);
+ for (int i = 1; i < 8; ++i) {
+ SkScalar a = 2.6927937f * i;
+ path.lineTo(C + R * cos(a), C + R * sin(a));
+ }
+ return path;
+}
+void draw(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setPathEffect(SkPathEffect::MakeSum(SkDiscretePathEffect::Make(10.0f, 4.0f),
+ SkDiscretePathEffect::Make(10.0f, 4.0f, 1245u)));
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(2.0f);
+ paint.setAntiAlias(true);
+ paint.setColor(0xff4285F4);
+ canvas->clear(SK_ColorWHITE);
+ SkPath path(star());
+ canvas->drawPath(path, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/sweep_gradient_talk_1.cpp b/docs/examples/sweep_gradient_talk_1.cpp
new file mode 100644
index 0000000..04f14c2
--- /dev/null
+++ b/docs/examples/sweep_gradient_talk_1.cpp
@@ -0,0 +1,14 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(sweep_gradient_talk_1, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkColor colors[] = {0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFF0000FF};
+ float cx = 128, cy = 128;
+ SkPaint paint;
+ paint.setShader(SkGradientShader::MakeSweep(cx, cy, colors, nullptr, 4));
+ paint.setAntiAlias(true);
+
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/sweep_gradient_talk_2.cpp b/docs/examples/sweep_gradient_talk_2.cpp
new file mode 100644
index 0000000..3e4f078
--- /dev/null
+++ b/docs/examples/sweep_gradient_talk_2.cpp
@@ -0,0 +1,17 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(sweep_gradient_talk_2, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ const float s = 1.0f / 6;
+ SkColor colors[] = {0xFF0000FF, 0xFF0000FF, 0xFF00FF00, 0xFF00FF00,
+ 0xFFFF0000, 0xFFFF0000, 0xFF0000FF, 0xFF0000FF};
+ float pos[] = {0, s, s, 3 * s, 3 * s, 5 * s, 5 * s, 1};
+ float cx = 128, cy = 128;
+ SkPaint paint;
+ paint.setShader(SkGradientShader::MakeSweep(cx, cy, colors, pos, 8));
+ paint.setAntiAlias(true);
+
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/sweep_gradient_talk_lots.cpp b/docs/examples/sweep_gradient_talk_lots.cpp
new file mode 100644
index 0000000..1f3c94b
--- /dev/null
+++ b/docs/examples/sweep_gradient_talk_lots.cpp
@@ -0,0 +1,16 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(sweep_gradient_talk_lots, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkRandom rand;
+ SkColor colors[100];
+ for (auto& color : colors) {
+ color = rand.nextU() | (0xFF << 24);
+ }
+ float cx = 128, cy = 128;
+ SkPaint paint;
+ paint.setShader(SkGradientShader::MakeSweep(cx, cy, colors, nullptr, 100));
+ canvas->drawPaint(paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/text_only.cpp b/docs/examples/text_only.cpp
new file mode 100644
index 0000000..4ad4d1b
--- /dev/null
+++ b/docs/examples/text_only.cpp
@@ -0,0 +1,6 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(text_only, 256, 256, true, 0) {
+void draw(SkCanvas* canvas) { SkDebugf("Hello World!"); }
+} // END FIDDLE
diff --git a/docs/examples/text_rendering.cpp b/docs/examples/text_rendering.cpp
new file mode 100644
index 0000000..f2d3c6e
--- /dev/null
+++ b/docs/examples/text_rendering.cpp
@@ -0,0 +1,41 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(text_rendering, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ const char* fontFamily = nullptr; // Default system family, if it exists.
+ SkFontStyle fontStyle; // Default is normal weight, normal width, upright slant.
+ sk_sp<SkFontMgr> fontManager = SkFontMgr::RefDefault();
+ sk_sp<SkTypeface> typeface = fontManager->legacyMakeTypeface(fontFamily, fontStyle);
+
+ SkFont font1(typeface, 64.0f, 1.0f, 0.0f);
+ SkFont font2(typeface, 64.0f, 1.5f, 0.0f);
+ font1.setEdging(SkFont::Edging::kAntiAlias);
+ font2.setEdging(SkFont::Edging::kAntiAlias);
+
+ // Note: MakeFromString may fail to produce expected results if the typeface
+ // does not have glyphs for the characters in the string. The characters
+ // will not be kerned or shaped beyond a simple mapping from one Unicode
+ // code point to one glyph with a default advance.
+ sk_sp<SkTextBlob> blob1 = SkTextBlob::MakeFromString("Skia", font1);
+ sk_sp<SkTextBlob> blob2 = SkTextBlob::MakeFromString("Skia", font2);
+
+ SkPaint paint1, paint2, paint3;
+
+ paint1.setAntiAlias(true);
+ paint1.setColor(SkColorSetARGB(0xFF, 0x42, 0x85, 0xF4));
+
+ paint2.setAntiAlias(true);
+ paint2.setColor(SkColorSetARGB(0xFF, 0xDB, 0x44, 0x37));
+ paint2.setStyle(SkPaint::kStroke_Style);
+ paint2.setStrokeWidth(3.0f);
+
+ paint3.setAntiAlias(true);
+ paint3.setColor(SkColorSetARGB(0xFF, 0x0F, 0x9D, 0x58));
+
+ canvas->clear(SK_ColorWHITE);
+ canvas->drawTextBlob(blob1.get(), 20.0f, 64.0f, paint1);
+ canvas->drawTextBlob(blob1.get(), 20.0f, 144.0f, paint2);
+ canvas->drawTextBlob(blob2.get(), 20.0f, 224.0f, paint3);
+}
+} // END FIDDLE
diff --git a/docs/examples/text_shadow.cpp b/docs/examples/text_shadow.cpp
new file mode 100644
index 0000000..34e64a5
--- /dev/null
+++ b/docs/examples/text_shadow.cpp
@@ -0,0 +1,23 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(text_shadow, 128, 64, false, 0) {
+void draw(SkCanvas* canvas) {
+ const SkScalar sigma = 1.65f;
+ const SkScalar xDrop = 2.0f;
+ const SkScalar yDrop = 2.0f;
+ const SkScalar x = 8.0f;
+ const SkScalar y = 52.0f;
+ const SkScalar textSize = 48.0f;
+ const uint8_t blurAlpha = 127;
+ auto blob = SkTextBlob::MakeFromString("Skia", SkFont(nullptr, textSize));
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkPaint blur(paint);
+ blur.setAlpha(blurAlpha);
+ blur.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma, 0));
+ canvas->drawColor(SK_ColorWHITE);
+ canvas->drawTextBlob(blob.get(), x + xDrop, y + yDrop, blur);
+ canvas->drawTextBlob(blob.get(), x, y, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/unexpected_setAlphaType.cpp b/docs/examples/unexpected_setAlphaType.cpp
new file mode 100644
index 0000000..52df753
--- /dev/null
+++ b/docs/examples/unexpected_setAlphaType.cpp
@@ -0,0 +1,65 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(unexpected_setAlphaType, 256, 256, true, 0) {
+static const char* alphatype_name(SkAlphaType at) {
+ switch (at) {
+ case kUnknown_SkAlphaType: return "Unknown";
+ case kOpaque_SkAlphaType: return "Opaque";
+ case kPremul_SkAlphaType: return "Premul";
+ case kUnpremul_SkAlphaType: return "Unpremul";
+ }
+ SkASSERT(false);
+ return "unexpected alphatype";
+}
+static const char* colortype_name(SkColorType ct) {
+ switch (ct) {
+ case kUnknown_SkColorType: return "Unknown";
+ case kAlpha_8_SkColorType: return "Alpha_8";
+ case kA16_unorm_SkColorType: return "Alpha_16";
+ case kA16_float_SkColorType: return "A16_float";
+ case kRGB_565_SkColorType: return "RGB_565";
+ case kARGB_4444_SkColorType: return "ARGB_4444";
+ case kRGBA_8888_SkColorType: return "RGBA_8888";
+ case kRGB_888x_SkColorType: return "RGB_888x";
+ case kBGRA_8888_SkColorType: return "BGRA_8888";
+ case kRGBA_1010102_SkColorType: return "RGBA_1010102";
+ case kRGB_101010x_SkColorType: return "RGB_101010x";
+ case kGray_8_SkColorType: return "Gray_8";
+ case kRGBA_F16Norm_SkColorType: return "RGBA_F16Norm";
+ case kRGBA_F16_SkColorType: return "RGBA_F16";
+ case kRGBA_F32_SkColorType: return "RGBA_F32";
+ case kR8G8_unorm_SkColorType: return "R8G8_unorm";
+ case kR16G16_unorm_SkColorType: return "R16G16_unorm";
+ case kR16G16_float_SkColorType: return "R16G16_float";
+ case kR16G16B16A16_unorm_SkColorType: return "R16G16B16A16_unorm";
+ }
+ SkASSERT(false);
+ return "unexpected colortype";
+}
+void draw(SkCanvas* canvas) {
+ static const SkAlphaType kAlphaTypes[] =
+ {kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType, kUnpremul_SkAlphaType};
+ static const SkColorType kColorTypes[] =
+ {kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
+ kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
+ kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
+ kGray_8_SkColorType, kRGBA_F16_SkColorType};
+ SkBitmap bitmap;
+ SkDebugf("%16s Canonical Unknown Opaque Premul "
+ "Unpremul\n", " ");
+ for (SkColorType colorType : kColorTypes) {
+ for (SkAlphaType canonicalAlphaType : kAlphaTypes) {
+ SkColorTypeValidateAlphaType(colorType, kUnknown_SkAlphaType, &canonicalAlphaType);
+ SkDebugf("%15s %10s ", colortype_name(colorType), alphatype_name(canonicalAlphaType));
+ for (SkAlphaType alphaType : kAlphaTypes) {
+ bitmap.setInfo(SkImageInfo::Make(4, 4, colorType, canonicalAlphaType));
+ bool result = bitmap.setAlphaType(alphaType);
+ SkDebugf("%s %s ", result ? "true " : "false",
+ alphatype_name(bitmap.alphaType()));
+ }
+ SkDebugf("\n");
+ }
+ }
+}
+} // END FIDDLE
diff --git a/docs/examples/upscale_checkerboard.cpp b/docs/examples/upscale_checkerboard.cpp
new file mode 100644
index 0000000..871309b
--- /dev/null
+++ b/docs/examples/upscale_checkerboard.cpp
@@ -0,0 +1,18 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(upscale_checkerboard, 512, 512, false, 0) {
+void draw(SkCanvas* canvas) {
+ SkPMColor p[] = {0xFFFFFFFF, 0xFF000000, 0xFF000000, 0xFFFFFFFF};
+ const auto info = SkImageInfo::MakeN32Premul(2, 2);
+ auto img = SkImage::MakeRasterCopy({info, p, 8});
+
+ SkPaint paint;
+ paint.setFilterQuality(kMedium_SkFilterQuality);
+ paint.setShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
+
+ canvas->translate(20, 20);
+ canvas->scale(20, 20);
+ canvas->drawRect({0, 0, 20, 20}, paint);
+}
+} // END FIDDLE
diff --git a/docs/examples/weird_RRect_bug.cpp b/docs/examples/weird_RRect_bug.cpp
new file mode 100644
index 0000000..1f9f01b
--- /dev/null
+++ b/docs/examples/weird_RRect_bug.cpp
@@ -0,0 +1,20 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(weird_RRect_bug, 256, 256, false, 0) {
+void draw(SkCanvas* canvas) {
+ canvas->clear(SK_ColorWHITE);
+ // canvas->scale(2, 2);
+
+ SkPaint p;
+ p.setAntiAlias(false);
+ p.setStrokeWidth(3);
+ p.setStyle(SkPaint::kStroke_Style);
+
+ SkRect r = SkRect::MakeXYWH(20, 20, 20, 20);
+
+ SkRRect rr = SkRRect::MakeRectXY(r, 5, 5);
+
+ canvas->drawRRect(rr, p);
+}
+} // END FIDDLE
diff --git a/docs/examples/zero_off_dashing.cpp b/docs/examples/zero_off_dashing.cpp
new file mode 100644
index 0000000..c0856b8
--- /dev/null
+++ b/docs/examples/zero_off_dashing.cpp
@@ -0,0 +1,33 @@
+// Copyright 2020 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+#include "tools/fiddle/examples.h"
+REG_FIDDLE(zero_off_dashing, 256, 256, false, 0) {
+static constexpr float kPi = 3.14159265358979323846f;
+void draw(SkCanvas* canvas) {
+ SkPaint p;
+ canvas->drawCircle(128, 128, 60, p);
+
+ p.setColor(0x88FF0000);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeCap(SkPaint::kSquare_Cap);
+ p.setStrokeWidth(80);
+ SkScalar interv[2] = {120 * kPi / 6 - 0.05f, 0.0000f};
+ p.setPathEffect(SkDashPathEffect::Make(interv, 2, 0.5));
+
+ SkPath path, path2;
+ path.addCircle(128, 128, 60);
+ canvas->drawPath(path, p);
+
+ p.setColor(0x8800FF00);
+ SkScalar interv2[2] = {120 * kPi / 6 - 0.05f, 10000.0000f};
+ p.setPathEffect(SkDashPathEffect::Make(interv2, 2, 0));
+ canvas->drawPath(path, p);
+
+ p.getFillPath(path, &path2);
+ p.setColor(0xFF000000);
+ p.setStrokeWidth(0);
+ p.setPathEffect(nullptr);
+ canvas->drawPath(path2, p);
+}
+} // END FIDDLE