grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp
new file mode 100644
index 0000000..6286045
--- /dev/null
+++ b/src/effects/SkDiscretePathEffect.cpp
@@ -0,0 +1,105 @@
+/* libs/graphics/effects/SkDiscretePathEffect.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "SkDiscretePathEffect.h"
+#include "SkBuffer.h"
+#include "SkPathMeasure.h"
+#include "SkRandom.h"
+
+static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale)
+{
+ SkVector normal = tangent;
+ normal.rotateCCW();
+ normal.setLength(scale);
+ *p += normal;
+}
+
+
+SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength, SkScalar deviation)
+ : fSegLength(segLength), fPerterb(deviation)
+{
+}
+
+bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width)
+{
+ bool doFill = *width < 0;
+
+ SkPathMeasure meas(src, doFill);
+ uint32_t seed = SkScalarRound(meas.getLength());
+ SkRandom rand(seed ^ ((seed << 16) | (seed >> 16)));
+ SkScalar scale = fPerterb;
+ SkPoint p;
+ SkVector v;
+
+ do {
+ SkScalar length = meas.getLength();
+
+ if (fSegLength * (2 + doFill) > length)
+ {
+ meas.getSegment(0, length, dst, true); // to short for us to mangle
+ }
+ else
+ {
+ int n = SkScalarRound(SkScalarDiv(length, fSegLength));
+ SkScalar delta = length / n;
+ SkScalar distance = 0;
+
+ if (meas.isClosed())
+ {
+ n -= 1;
+ distance += delta/2;
+ }
+ meas.getPosTan(distance, &p, &v);
+ Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
+ dst->moveTo(p);
+ while (--n >= 0)
+ {
+ distance += delta;
+ meas.getPosTan(distance, &p, &v);
+ Perterb(&p, v, SkScalarMul(rand.nextSScalar1(), scale));
+ dst->lineTo(p);
+ }
+ if (meas.isClosed())
+ dst->close();
+ }
+ } while (meas.nextContour());
+ return true;
+}
+
+SkFlattenable::Factory SkDiscretePathEffect::getFactory()
+{
+ return CreateProc;
+}
+
+SkFlattenable* SkDiscretePathEffect::CreateProc(SkFlattenableReadBuffer& buffer)
+{
+ return SkNEW_ARGS(SkDiscretePathEffect, (buffer));
+}
+
+void SkDiscretePathEffect::flatten(SkFlattenableWriteBuffer& buffer)
+{
+ buffer.writeScalar(fSegLength);
+ buffer.writeScalar(fPerterb);
+}
+
+SkDiscretePathEffect::SkDiscretePathEffect(SkFlattenableReadBuffer& buffer)
+{
+ fSegLength = buffer.readScalar();
+ fPerterb = buffer.readScalar();
+}
+
+