blob: 8aa0e223562d39a28c9f8a1a29c38dbfb31f4e85 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#include "SkDiscretePathEffect.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000011#include "SkReadBuffer.h"
12#include "SkWriteBuffer.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000013#include "SkPathMeasure.h"
14#include "SkRandom.h"
15
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000016static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000017 SkVector normal = tangent;
18 normal.rotateCCW();
19 normal.setLength(scale);
20 *p += normal;
21}
22
rs.prinja39e58ad2014-06-12 22:55:08 -070023SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength,
24 SkScalar deviation,
25 uint32_t seedAssist)
26 : fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
reed@android.com8a1c16f2008-12-17 15:59:43 +000027{
28}
29
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000030bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src,
reed@google.com4bbdeac2013-01-24 21:03:11 +000031 SkStrokeRec* rec, const SkRect*) const {
reed@google.comfd4be262012-05-25 01:04:12 +000032 bool doFill = rec->isFillStyle();
reed@android.com8a1c16f2008-12-17 15:59:43 +000033
34 SkPathMeasure meas(src, doFill);
rs.prinja39e58ad2014-06-12 22:55:08 -070035
36 /* Caller may supply their own seed assist, which by default is 0 */
37 uint32_t seed = fSeedAssist ^ SkScalarRoundToInt(meas.getLength());
38
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000039 SkLCGRandom rand(seed ^ ((seed << 16) | (seed >> 16)));
reed@android.com8a1c16f2008-12-17 15:59:43 +000040 SkScalar scale = fPerterb;
41 SkPoint p;
42 SkVector v;
43
44 do {
45 SkScalar length = meas.getLength();
46
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000047 if (fSegLength * (2 + doFill) > length) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000048 meas.getSegment(0, length, dst, true); // to short for us to mangle
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000049 } else {
reed@google.come1ca7052013-12-17 19:22:07 +000050 int n = SkScalarRoundToInt(length / fSegLength);
reed@android.com8a1c16f2008-12-17 15:59:43 +000051 SkScalar delta = length / n;
52 SkScalar distance = 0;
53
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000054 if (meas.isClosed()) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000055 n -= 1;
56 distance += delta/2;
57 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000058
reed@google.comf3edf9f2012-04-12 19:44:38 +000059 if (meas.getPosTan(distance, &p, &v)) {
60 Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
61 dst->moveTo(p);
62 }
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000063 while (--n >= 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 distance += delta;
reed@google.comf3edf9f2012-04-12 19:44:38 +000065 if (meas.getPosTan(distance, &p, &v)) {
66 Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
67 dst->lineTo(p);
68 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 }
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000070 if (meas.isClosed()) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000071 dst->close();
mike@reedtribe.org3334c3a2011-04-20 11:39:28 +000072 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000073 }
74 } while (meas.nextContour());
75 return true;
76}
77
reed9fa60da2014-08-21 07:59:51 -070078SkFlattenable* SkDiscretePathEffect::CreateProc(SkReadBuffer& buffer) {
79 SkScalar segLength = buffer.readScalar();
80 SkScalar perterb = buffer.readScalar();
81 uint32_t seed = buffer.readUInt();
82 return Create(segLength, perterb, seed);
83}
84
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000085void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000086 buffer.writeScalar(fSegLength);
87 buffer.writeScalar(fPerterb);
rs.prinja39e58ad2014-06-12 22:55:08 -070088 buffer.writeUInt(fSeedAssist);
reed@android.com8a1c16f2008-12-17 15:59:43 +000089}