3 * Copyright 2006 The Android Open Source Project
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #include "SkDiscretePathEffect.h"
11 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h"
13 #include "SkPathMeasure.h"
16 static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) {
17 SkVector normal = tangent;
19 normal.setLength(scale);
23 SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength,
26 : fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
30 bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src,
31 SkStrokeRec* rec, const SkRect*) const {
32 bool doFill = rec->isFillStyle();
34 SkPathMeasure meas(src, doFill);
36 /* Caller may supply their own seed assist, which by default is 0 */
37 uint32_t seed = fSeedAssist ^ SkScalarRoundToInt(meas.getLength());
39 SkLCGRandom rand(seed ^ ((seed << 16) | (seed >> 16)));
40 SkScalar scale = fPerterb;
45 SkScalar length = meas.getLength();
47 if (fSegLength * (2 + doFill) > length) {
48 meas.getSegment(0, length, dst, true); // to short for us to mangle
50 int n = SkScalarRoundToInt(length / fSegLength);
51 SkScalar delta = length / n;
52 SkScalar distance = 0;
54 if (meas.isClosed()) {
59 if (meas.getPosTan(distance, &p, &v)) {
60 Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
65 if (meas.getPosTan(distance, &p, &v)) {
66 Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
70 if (meas.isClosed()) {
74 } while (meas.nextContour());
78 SkFlattenable* 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);
85 void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
86 buffer.writeScalar(fSegLength);
87 buffer.writeScalar(fPerterb);
88 buffer.writeUInt(fSeedAssist);
91 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
92 SkDiscretePathEffect::SkDiscretePathEffect(SkReadBuffer& buffer) {
93 fSegLength = buffer.readScalar();
94 fPerterb = buffer.readScalar();
95 fSeedAssist = buffer.readUInt();