diff options
author | caryclark <caryclark@google.com> | 2016-01-19 08:07:49 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-19 08:07:50 -0800 |
commit | b6474dd1a530a543ae799c3822e8bc60180761c0 (patch) | |
tree | 2e42f77ea502e31ac7473806437adb6be680bd33 /gm/dashcircle.cpp | |
parent | a913275bda105fd545af471b724d7e8c1dacb9ae (diff) |
fix circular dashing
Path measure cannot use the same code approach for quadratics
and cubics. Subdividing cubics repeatedly does not result in
subdivided t values, e.g. a quarter circle cubic divided in
half twice does not have a t value equivalent to 1/4.
Instead, always compute the cubic segment from a pair of
t values.
When finding the length of the cubic through recursive measures,
it is enough to carry the point at a given t to the next
subdivision.
(Chrome suppression has landed already.)
R=reed@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1602153002
Review URL: https://codereview.chromium.org/1602153002
Diffstat (limited to 'gm/dashcircle.cpp')
-rw-r--r-- | gm/dashcircle.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/gm/dashcircle.cpp b/gm/dashcircle.cpp new file mode 100644 index 0000000000..cddd913723 --- /dev/null +++ b/gm/dashcircle.cpp @@ -0,0 +1,78 @@ +/* + * 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 "gm.h" +#include "SkPath.h" +#include "SkDashPathEffect.h" + +int dash1[] = { 1, 1 }; +int dash2[] = { 1, 3 }; +int dash3[] = { 1, 1, 3, 3 }; +int dash4[] = { 1, 3, 2, 4 }; + +struct DashExample { + int* pattern; + int length; +} dashExamples[] = { + { dash1, SK_ARRAY_COUNT(dash1) }, + { dash2, SK_ARRAY_COUNT(dash2) }, + { dash3, SK_ARRAY_COUNT(dash3) }, + { dash4, SK_ARRAY_COUNT(dash4) } +}; + +DEF_SIMPLE_GM(dashcircle, canvas, 900, 1200) { + SkPaint refPaint; + refPaint.setAntiAlias(true); + refPaint.setColor(0xFFbf3f7f); + refPaint.setStyle(SkPaint::kStroke_Style); + refPaint.setStrokeWidth(1); + const SkScalar radius = 125; + SkRect oval = SkRect::MakeLTRB(-radius - 20, -radius - 20, radius + 20, radius + 20); + SkPath circle; + circle.addCircle(0, 0, radius); + SkScalar circumference = radius * SK_ScalarPI * 2; + int wedges[] = { 6, 12, 36 }; + canvas->translate(radius + 20, radius + 20); + for (int wedge : wedges) { + SkScalar arcLength = 360.f / wedge; + canvas->save(); + for (const DashExample& dashExample : dashExamples) { + SkPath refPath; + int dashUnits = 0; + for (int index = 0; index < dashExample.length; ++index) { + dashUnits += dashExample.pattern[index]; + } + SkScalar unitLength = arcLength / dashUnits; + SkScalar angle = 0; + for (int index = 0; index < wedge; ++index) { + for (int i2 = 0; i2 < dashExample.length; i2 += 2) { + SkScalar span = dashExample.pattern[i2] * unitLength; + refPath.moveTo(0, 0); + refPath.arcTo(oval, angle, span, false); + refPath.close(); + angle += span + (dashExample.pattern[i2 + 1]) * unitLength; + } + } + canvas->drawPath(refPath, refPaint); + SkPaint p; + p.setAntiAlias(true); + p.setStyle(SkPaint::kStroke_Style); + p.setStrokeWidth(10); + SkScalar intervals[4]; + int intervalCount = dashExample.length; + SkScalar dashLength = circumference / wedge / dashUnits; + for (int index = 0; index < dashExample.length; ++index) { + intervals[index] = dashExample.pattern[index] * dashLength; + } + p.setPathEffect(SkDashPathEffect::Create(intervals, intervalCount, 0))->unref(); + canvas->drawPath(circle, p); + canvas->translate(0, radius * 2 + 50); + } + canvas->restore(); + canvas->translate(radius * 2 + 50, 0); + } +} |