aboutsummaryrefslogtreecommitdiffhomepage
path: root/samplecode
diff options
context:
space:
mode:
authorGravatar hstern <hstern@google.com>2016-06-15 09:13:34 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-15 09:13:35 -0700
commit9bd4c693020bb440464ae12ae05e8e8f97568ee0 (patch)
tree60cd5c367438c52f4f07a98ce7c1fca4baba434c /samplecode
parentf130b8299ba47085bdc0e5443fdec492191978ed (diff)
Add SampleApp that shows problems in stroking
- When the stroke width gets too big the raster algorithm produces incorrect output - This also causes the GPU path to produce incorrect output if the width is larger than an arbitrary limit in GrAALinearizingConvexPathRenderer (which is the renderer used for this specific geometry) - Other non-convex geometries probably also produce strange results BUG=skia:5405,skia:5406 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2060903002 Review-Url: https://codereview.chromium.org/2060903002
Diffstat (limited to 'samplecode')
-rw-r--r--samplecode/SamplePathOverstroke.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/samplecode/SamplePathOverstroke.cpp b/samplecode/SamplePathOverstroke.cpp
new file mode 100644
index 0000000000..8219065658
--- /dev/null
+++ b/samplecode/SamplePathOverstroke.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkPath.h"
+
+#include <cmath>
+
+#define PI SK_ScalarPI
+
+#define LIN_SEGMENTS 10
+
+class OverstrokeView : public SampleView {
+ public:
+ SkScalar fStroke;
+ int fPathType; // super lazy enum
+ bool fClosePath;
+ bool fDrawFillPath;
+ OverstrokeView() {
+ fStroke = 5;
+ fPathType = 0;
+ fClosePath = false;
+ fDrawFillPath = false;
+ this->setBGColor(0xFFFFFFFF);
+ }
+
+ protected:
+ bool onQuery(SkEvent* evt) override {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "PathOverstroke");
+ return true;
+ }
+ SkUnichar uni;
+ if (SampleCode::CharQ(*evt, &uni)) {
+ switch (uni) {
+ case ',':
+ fStroke += 1.0;
+ this->inval(nullptr);
+ return true;
+ case '.':
+ fStroke -= 1.0;
+ this->inval(nullptr);
+ return true;
+ case 'x':
+ fPathType = (fPathType + 1) % 3;
+ this->inval(nullptr);
+ return true;
+ case 'c':
+ fClosePath = !fClosePath;
+ this->inval(nullptr);
+ return true;
+ case 'f':
+ fDrawFillPath = !fDrawFillPath;
+ this->inval(nullptr);
+ return true;
+ default:
+ break;
+ }
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+ SkPath quadPath(SkPoint p1, SkPoint p2) {
+ SkASSERT(p1.y() == p2.y());
+
+ SkPath path;
+ path.moveTo(p1);
+ path.lineTo(p2);
+
+ SkPoint p3 = SkPoint::Make((p1.x() + p2.x()) / 2.0f, p1.y() * 0.7f);
+
+ path.quadTo(p3, p1);
+
+ return path;
+ }
+
+ SkPath linSemicirclePath(SkPoint p1, SkPoint p2) {
+ SkASSERT(p1.y() == p2.y());
+
+ SkPath path;
+ path.moveTo(p1);
+ path.lineTo(p2);
+
+ SkPoint pt;
+
+ for (int i = 0; i < LIN_SEGMENTS; i++) {
+ float theta = i * PI / (LIN_SEGMENTS);
+ SkScalar x = 65 + 15 * cos(theta);
+ SkScalar y = 50 - 15 * sin(theta);
+ pt = SkPoint::Make(x, y);
+ path.lineTo(pt);
+ }
+ path.lineTo(p1);
+
+ return path;
+ }
+
+ SkPath rectPath(SkPoint p1) {
+ SkRect r = SkRect::MakeXYWH(p1.fX, p1.fY, 20, 20);
+ SkPath path;
+ path.addRect(r);
+
+ return path;
+ }
+
+ void onDrawContent(SkCanvas* canvas) override {
+ const float SCALE = 1;
+
+ canvas->translate(30, 40);
+ canvas->scale(SCALE, SCALE);
+
+ SkPoint p1 = SkPoint::Make(50, 50);
+ SkPoint p2 = SkPoint::Make(80, 50);
+
+ SkPath path;
+ switch (fPathType) {
+ case 0:
+ path = quadPath(p1, p2);
+ break;
+ case 1:
+ path = linSemicirclePath(p1, p2);
+ break;
+ case 2:
+ path = rectPath(p1);
+ break;
+ default:
+ path = quadPath(p1, p2);
+ break;
+ }
+
+ if (fClosePath) {
+ path.close();
+ }
+
+ SkPaint p;
+ p.setColor(SK_ColorRED);
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(fStroke);
+
+ canvas->drawPath(path, p);
+
+ if (fDrawFillPath) {
+ SkPath fillpath;
+ p.getFillPath(path, &fillpath);
+
+ SkPaint fillp;
+ fillp.setColor(SK_ColorBLACK);
+ fillp.setAntiAlias(true);
+ fillp.setStyle(SkPaint::kStroke_Style);
+
+ canvas->drawPath(fillpath, fillp);
+ }
+ }
+
+ private:
+ typedef SampleView INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new OverstrokeView; }
+static SkViewRegister reg(MyFactory);