aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/OverStroke.cpp108
1 files changed, 73 insertions, 35 deletions
diff --git a/gm/OverStroke.cpp b/gm/OverStroke.cpp
index 0c5679786c..f7134cd26c 100644
--- a/gm/OverStroke.cpp
+++ b/gm/OverStroke.cpp
@@ -13,6 +13,12 @@
* overlap and create holes. There is not a really great algorithm for this
* and several other 2D graphics engines have the same bug.
*
+ * If we run this using Nvidia Path Renderer with:
+ * `path/to/dm --match OverStroke -w gm_out --gpu --config nvpr16`
+ * then we get correct results, so that is a possible direction of attack -
+ * use the GPU and a completely different algorithm to get correctness in
+ * Skia.
+ *
* See crbug.com/589769 skbug.com/5405 skbug.com/5406
*/
@@ -20,14 +26,28 @@
#include "gm.h"
#include "SkPaint.h"
#include "SkPath.h"
+#include "SkPathMeasure.h"
+
+const SkScalar OVERSTROKE_WIDTH = 500.0f;
+const SkScalar NORMALSTROKE_WIDTH = 3.0f;
//////// path and paint builders
+SkPaint make_normal_paint() {
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(NORMALSTROKE_WIDTH);
+ p.setColor(SK_ColorBLUE);
+
+ return p;
+}
+
SkPaint make_overstroke_paint() {
SkPaint p;
p.setAntiAlias(true);
p.setStyle(SkPaint::kStroke_Style);
- p.setStrokeWidth(500);
+ p.setStrokeWidth(OVERSTROKE_WIDTH);
return p;
}
@@ -38,6 +58,7 @@ SkPath quad_path() {
path.lineTo(100, 0);
path.quadTo(50, -40,
0, 0);
+ path.close();
return path;
}
@@ -62,19 +83,50 @@ SkPath oval_path() {
return path;
}
+SkPath ribs_path(SkPath path, SkScalar radius) {
+ SkPath ribs;
+
+ const SkScalar spacing = 5.0f;
+ float accum = 0.0f;
+
+ SkPathMeasure meas(path, false);
+ SkScalar length = meas.getLength();
+ SkPoint pos;
+ SkVector tan;
+ while (accum < length) {
+ if (meas.getPosTan(accum, &pos, &tan)) {
+ tan.scale(radius);
+ tan.rotateCCW();
+
+ ribs.moveTo(pos.x() + tan.x(), pos.y() + tan.y());
+ ribs.lineTo(pos.x() - tan.x(), pos.y() - tan.y());
+ }
+ accum += spacing;
+ }
+
+ return ribs;
+}
+
+void draw_ribs(SkCanvas *canvas, SkPath path) {
+ SkPath ribs = ribs_path(path, OVERSTROKE_WIDTH/2.0f);
+ SkPaint p = make_normal_paint();
+ p.setStrokeWidth(1);
+ p.setColor(SK_ColorBLUE);
+ p.setColor(SK_ColorGREEN);
+
+ canvas->drawPath(ribs, p);
+}
+
///////// quads
void draw_small_quad(SkCanvas *canvas) {
// scaled so it's visible
- canvas->scale(8, 8);
-
- SkPaint p;
- p.setAntiAlias(true);
- p.setStyle(SkPaint::kStroke_Style);
- p.setStrokeWidth(3);
+ // canvas->scale(8, 8);
+ SkPaint p = make_normal_paint();
SkPath path = quad_path();
+ draw_ribs(canvas, path);
canvas->drawPath(path, p);
}
@@ -83,15 +135,14 @@ void draw_large_quad(SkCanvas *canvas) {
SkPath path = quad_path();
canvas->drawPath(path, p);
+ draw_ribs(canvas, path);
}
void draw_quad_fillpath(SkCanvas *canvas) {
SkPath path = quad_path();
SkPaint p = make_overstroke_paint();
- SkPaint fillp;
- fillp.setAntiAlias(true);
- fillp.setStyle(SkPaint::kStroke_Style);
+ SkPaint fillp = make_normal_paint();
fillp.setColor(SK_ColorMAGENTA);
SkPath fillpath;
@@ -101,7 +152,7 @@ void draw_quad_fillpath(SkCanvas *canvas) {
}
void draw_stroked_quad(SkCanvas *canvas) {
- canvas->translate(200, 0);
+ canvas->translate(400, 0);
draw_large_quad(canvas);
draw_quad_fillpath(canvas);
}
@@ -109,16 +160,10 @@ void draw_stroked_quad(SkCanvas *canvas) {
////////// cubics
void draw_small_cubic(SkCanvas *canvas) {
- // scaled so it's visible
- canvas->scale(8, 8);
-
- SkPaint p;
- p.setAntiAlias(true);
- p.setStyle(SkPaint::kStroke_Style);
- p.setStrokeWidth(3);
-
+ SkPaint p = make_normal_paint();
SkPath path = cubic_path();
+ draw_ribs(canvas, path);
canvas->drawPath(path, p);
}
@@ -127,15 +172,14 @@ void draw_large_cubic(SkCanvas *canvas) {
SkPath path = cubic_path();
canvas->drawPath(path, p);
+ draw_ribs(canvas, path);
}
void draw_cubic_fillpath(SkCanvas *canvas) {
SkPath path = cubic_path();
SkPaint p = make_overstroke_paint();
- SkPaint fillp;
- fillp.setAntiAlias(true);
- fillp.setStyle(SkPaint::kStroke_Style);
+ SkPaint fillp = make_normal_paint();
fillp.setColor(SK_ColorMAGENTA);
SkPath fillpath;
@@ -153,16 +197,11 @@ void draw_stroked_cubic(SkCanvas *canvas) {
////////// ovals
void draw_small_oval(SkCanvas *canvas) {
- // scaled so it's visible
- canvas->scale(8, 8);
-
- SkPaint p;
- p.setAntiAlias(true);
- p.setStyle(SkPaint::kStroke_Style);
- p.setStrokeWidth(3);
+ SkPaint p = make_normal_paint();
SkPath path = oval_path();
+ draw_ribs(canvas, path);
canvas->drawPath(path, p);
}
@@ -171,15 +210,14 @@ void draw_large_oval(SkCanvas *canvas) {
SkPath path = oval_path();
canvas->drawPath(path, p);
+ draw_ribs(canvas, path);
}
void draw_oval_fillpath(SkCanvas *canvas) {
SkPath path = oval_path();
SkPaint p = make_overstroke_paint();
- SkPaint fillp;
- fillp.setAntiAlias(true);
- fillp.setStyle(SkPaint::kStroke_Style);
+ SkPaint fillp = make_normal_paint();
fillp.setColor(SK_ColorMAGENTA);
SkPath fillpath;
@@ -210,9 +248,9 @@ DEF_SIMPLE_GM(OverStroke, canvas, 500, 500) {
int y = (int)(i / width);
canvas->save();
- canvas->translate(200.0f * x, 150.0f * y);
- canvas->scale(0.25f, 0.25f);
- canvas->translate(100.0f, 400.0f);
+ canvas->translate(150.0f * x, 150.0f * y);
+ canvas->scale(0.2f, 0.2f);
+ canvas->translate(300.0f, 400.0f);
examples[i](canvas);