SkDiscretePathEffect.cpp revision 8b0e8ac5f582de80356019406e2975079bf0829d
1 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 9 10#include "SkDiscretePathEffect.h" 11#include "SkReadBuffer.h" 12#include "SkWriteBuffer.h" 13#include "SkPathMeasure.h" 14#include "SkRandom.h" 15 16static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) { 17 SkVector normal = tangent; 18 normal.rotateCCW(); 19 normal.setLength(scale); 20 *p += normal; 21} 22 23 24SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength, SkScalar deviation) 25 : fSegLength(segLength), fPerterb(deviation) 26{ 27} 28 29bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src, 30 SkStrokeRec* rec, const SkRect*) const { 31 bool doFill = rec->isFillStyle(); 32 33 SkPathMeasure meas(src, doFill); 34 uint32_t seed = SkScalarRoundToInt(meas.getLength()); 35 SkLCGRandom rand(seed ^ ((seed << 16) | (seed >> 16))); 36 SkScalar scale = fPerterb; 37 SkPoint p; 38 SkVector v; 39 40 do { 41 SkScalar length = meas.getLength(); 42 43 if (fSegLength * (2 + doFill) > length) { 44 meas.getSegment(0, length, dst, true); // to short for us to mangle 45 } else { 46 int n = SkScalarRoundToInt(length / fSegLength); 47 SkScalar delta = length / n; 48 SkScalar distance = 0; 49 50 if (meas.isClosed()) { 51 n -= 1; 52 distance += delta/2; 53 } 54 55 if (meas.getPosTan(distance, &p, &v)) { 56 Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 57 dst->moveTo(p); 58 } 59 while (--n >= 0) { 60 distance += delta; 61 if (meas.getPosTan(distance, &p, &v)) { 62 Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 63 dst->lineTo(p); 64 } 65 } 66 if (meas.isClosed()) { 67 dst->close(); 68 } 69 } 70 } while (meas.nextContour()); 71 return true; 72} 73 74void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const { 75 this->INHERITED::flatten(buffer); 76 buffer.writeScalar(fSegLength); 77 buffer.writeScalar(fPerterb); 78} 79 80SkDiscretePathEffect::SkDiscretePathEffect(SkReadBuffer& buffer) { 81 fSegLength = buffer.readScalar(); 82 fPerterb = buffer.readScalar(); 83} 84