1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/effects/SkDiscretePathEffect.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,83 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkDiscretePathEffect.h" 1.14 +#include "SkReadBuffer.h" 1.15 +#include "SkWriteBuffer.h" 1.16 +#include "SkPathMeasure.h" 1.17 +#include "SkRandom.h" 1.18 + 1.19 +static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) { 1.20 + SkVector normal = tangent; 1.21 + normal.rotateCCW(); 1.22 + normal.setLength(scale); 1.23 + *p += normal; 1.24 +} 1.25 + 1.26 + 1.27 +SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength, SkScalar deviation) 1.28 + : fSegLength(segLength), fPerterb(deviation) 1.29 +{ 1.30 +} 1.31 + 1.32 +bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src, 1.33 + SkStrokeRec* rec, const SkRect*) const { 1.34 + bool doFill = rec->isFillStyle(); 1.35 + 1.36 + SkPathMeasure meas(src, doFill); 1.37 + uint32_t seed = SkScalarRoundToInt(meas.getLength()); 1.38 + SkLCGRandom rand(seed ^ ((seed << 16) | (seed >> 16))); 1.39 + SkScalar scale = fPerterb; 1.40 + SkPoint p; 1.41 + SkVector v; 1.42 + 1.43 + do { 1.44 + SkScalar length = meas.getLength(); 1.45 + 1.46 + if (fSegLength * (2 + doFill) > length) { 1.47 + meas.getSegment(0, length, dst, true); // to short for us to mangle 1.48 + } else { 1.49 + int n = SkScalarRoundToInt(length / fSegLength); 1.50 + SkScalar delta = length / n; 1.51 + SkScalar distance = 0; 1.52 + 1.53 + if (meas.isClosed()) { 1.54 + n -= 1; 1.55 + distance += delta/2; 1.56 + } 1.57 + 1.58 + if (meas.getPosTan(distance, &p, &v)) { 1.59 + Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 1.60 + dst->moveTo(p); 1.61 + } 1.62 + while (--n >= 0) { 1.63 + distance += delta; 1.64 + if (meas.getPosTan(distance, &p, &v)) { 1.65 + Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale)); 1.66 + dst->lineTo(p); 1.67 + } 1.68 + } 1.69 + if (meas.isClosed()) { 1.70 + dst->close(); 1.71 + } 1.72 + } 1.73 + } while (meas.nextContour()); 1.74 + return true; 1.75 +} 1.76 + 1.77 +void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const { 1.78 + this->INHERITED::flatten(buffer); 1.79 + buffer.writeScalar(fSegLength); 1.80 + buffer.writeScalar(fPerterb); 1.81 +} 1.82 + 1.83 +SkDiscretePathEffect::SkDiscretePathEffect(SkReadBuffer& buffer) { 1.84 + fSegLength = buffer.readScalar(); 1.85 + fPerterb = buffer.readScalar(); 1.86 +}