| Index: samplecode/SampleQuadStroker.cpp
|
| diff --git a/samplecode/SampleQuadStroker.cpp b/samplecode/SampleQuadStroker.cpp
|
| index 3b029804adc5bc8c9665131307e195fd1f99a790..88f7dfd4aea1667a2b3a31a2aaf1918f9de1d2e9 100644
|
| --- a/samplecode/SampleQuadStroker.cpp
|
| +++ b/samplecode/SampleQuadStroker.cpp
|
| @@ -9,6 +9,7 @@
|
| #include "SampleCode.h"
|
| #include "SkView.h"
|
| #include "SkCanvas.h"
|
| +#include "SkGeometry.h"
|
| #include "SkPathMeasure.h"
|
| #include "SkRandom.h"
|
| #include "SkRRect.h"
|
| @@ -122,6 +123,7 @@ class QuadStrokerView : public SampleView {
|
| bool fAnimate;
|
| bool fDrawRibs;
|
| bool fDrawTangents;
|
| + bool fDrawTDivs;
|
| #ifdef SK_DEBUG
|
| #define kStrokerErrorMin 0.001f
|
| #define kStrokerErrorMax 5
|
| @@ -288,16 +290,84 @@ protected:
|
| SkScalar total = meas.getLength();
|
|
|
| SkScalar delta = 8;
|
| - SkPaint paint;
|
| + SkPaint paint, labelP;
|
| paint.setColor(color);
|
| -
|
| + labelP.setColor(color & 0xff5f9f5f);
|
| SkPoint pos, tan;
|
| + int index = 0;
|
| for (SkScalar dist = 0; dist <= total; dist += delta) {
|
| if (meas.getPosTan(dist, &pos, &tan)) {
|
| tan.scale(radius);
|
| tan.rotateCCW();
|
| canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(),
|
| pos.x() - tan.x(), pos.y() - tan.y(), paint);
|
| + if (0 == index % 10) {
|
| + SkString label;
|
| + label.appendS32(index);
|
| + SkRect dot = SkRect::MakeXYWH(pos.x() - 2, pos.y() - 2, 4, 4);
|
| + canvas->drawRect(dot, labelP);
|
| + canvas->drawText(label.c_str(), label.size(),
|
| + pos.x() - tan.x() * 1.25f, pos.y() - tan.y() * 1.25f, labelP);
|
| + }
|
| + }
|
| + ++index;
|
| + }
|
| + }
|
| +
|
| + void draw_t_divs(SkCanvas* canvas, const SkPath& path, SkScalar width, SkColor color) {
|
| + const SkScalar radius = width / 2;
|
| + SkPaint paint;
|
| + paint.setColor(color);
|
| + SkPathMeasure meas(path, false);
|
| + SkScalar total = meas.getLength();
|
| + SkScalar delta = 8;
|
| + int ribs = 0;
|
| + for (SkScalar dist = 0; dist <= total; dist += delta) {
|
| + ++ribs;
|
| + }
|
| + SkPath::RawIter iter(path);
|
| + SkPoint pts[4];
|
| + if (SkPath::kMove_Verb != iter.next(pts)) {
|
| + SkASSERT(0);
|
| + return;
|
| + }
|
| + SkPath::Verb verb = iter.next(pts);
|
| + SkASSERT(SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb);
|
| + SkPoint pos, tan;
|
| + for (int index = 0; index < ribs; ++index) {
|
| + SkScalar t = (SkScalar) index / ribs;
|
| + switch (verb) {
|
| + case SkPath::kLine_Verb:
|
| + tan = pts[1] - pts[0];
|
| + pos = pts[0];
|
| + pos.fX += tan.fX * t;
|
| + pos.fY += tan.fY * t;
|
| + break;
|
| + case SkPath::kQuad_Verb:
|
| + pos = SkEvalQuadAt(pts, t);
|
| + tan = SkEvalQuadTangentAt(pts, t);
|
| + break;
|
| + case SkPath::kConic_Verb: {
|
| + SkConic conic(pts, iter.conicWeight());
|
| + pos = conic.evalAt(t);
|
| + tan = conic.evalTangentAt(t);
|
| + } break;
|
| + case SkPath::kCubic_Verb:
|
| + SkEvalCubicAt(pts, t, &pos, &tan, nullptr);
|
| + break;
|
| + default:
|
| + SkASSERT(0);
|
| + return;
|
| + }
|
| + tan.setLength(radius);
|
| + tan.rotateCCW();
|
| + canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(),
|
| + pos.x() - tan.x(), pos.y() - tan.y(), paint);
|
| + if (0 == index % 10) {
|
| + SkString label;
|
| + label.appendS32(index);
|
| + canvas->drawText(label.c_str(), label.size(),
|
| + pos.x() + tan.x() * 1.25f, pos.y() + tan.y() * 1.25f, paint);
|
| }
|
| }
|
| }
|
| @@ -343,6 +413,10 @@ protected:
|
| draw_ribs(canvas, scaled, width, 0xFF00FF00);
|
| }
|
|
|
| + if (fDrawTDivs) {
|
| + draw_t_divs(canvas, scaled, width, 0xFF3F3F00);
|
| + }
|
| +
|
| SkPath fill;
|
|
|
| SkPaint p;
|
| @@ -428,17 +502,24 @@ protected:
|
| void setForGeometry() {
|
| fDrawRibs = true;
|
| fDrawTangents = true;
|
| + fDrawTDivs = false;
|
| fWidthScale = 1;
|
| }
|
|
|
| void setForText() {
|
| - fDrawRibs = fDrawTangents = false;
|
| + fDrawRibs = fDrawTangents = fDrawTDivs = false;
|
| fWidthScale = 0.002f;
|
| }
|
|
|
| + void setForSingles() {
|
| + setForGeometry();
|
| + fDrawTDivs = true;
|
| + }
|
| +
|
| void setAsNeeded() {
|
| - if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabled
|
| - || fRRectButton.fEnabled || fCircleButton.fEnabled) {
|
| + if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabled) {
|
| + setForSingles();
|
| + } else if (fRRectButton.fEnabled || fCircleButton.fEnabled) {
|
| setForGeometry();
|
| } else {
|
| setForText();
|
| @@ -452,14 +533,15 @@ protected:
|
| if (fCubicButton.fEnabled) {
|
| path.moveTo(fPts[0]);
|
| path.cubicTo(fPts[1], fPts[2], fPts[3]);
|
| - setForGeometry();
|
| + setForSingles();
|
| draw_stroke(canvas, path, width, 950, false);
|
| }
|
|
|
| if (fConicButton.fEnabled) {
|
| + path.reset();
|
| path.moveTo(fPts[4]);
|
| path.conicTo(fPts[5], fPts[6], fWeight);
|
| - setForGeometry();
|
| + setForSingles();
|
| draw_stroke(canvas, path, width, 950, false);
|
| }
|
|
|
| @@ -467,7 +549,7 @@ protected:
|
| path.reset();
|
| path.moveTo(fPts[7]);
|
| path.quadTo(fPts[8], fPts[9]);
|
| - setForGeometry();
|
| + setForSingles();
|
| draw_stroke(canvas, path, width, 950, false);
|
| }
|
|
|
|
|