grab from latest android



git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/Sk2DPathEffect.cpp b/src/effects/Sk2DPathEffect.cpp
new file mode 100644
index 0000000..405b194
--- /dev/null
+++ b/src/effects/Sk2DPathEffect.cpp
@@ -0,0 +1,107 @@
+/* libs/graphics/effects/Sk2DPathEffect.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 "Sk2DPathEffect.h"
+#include "SkBlitter.h"
+#include "SkPath.h"
+#include "SkScan.h"
+
+class Sk2DPathEffectBlitter : public SkBlitter {
+public:
+    Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst)
+        : fPE(pe), fDst(dst)
+    {}
+    virtual void blitH(int x, int y, int count)
+    {
+        fPE->nextSpan(x, y, count, fDst);
+    }
+private:
+    Sk2DPathEffect* fPE;
+    SkPath*         fDst;
+};
+
+////////////////////////////////////////////////////////////////////////////////////
+
+Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat)
+{
+    mat.invert(&fInverse);
+}
+
+bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width)
+{
+    Sk2DPathEffectBlitter   blitter(this, dst);
+    SkPath                  tmp;
+    SkRect                  bounds;
+    SkIRect                 ir;
+
+    src.transform(fInverse, &tmp);
+    tmp.computeBounds(&bounds, SkPath::kExact_BoundsType);
+    bounds.round(&ir);
+    if (!ir.isEmpty()) {
+        // need to pass a clip to fillpath, required for inverse filltypes,
+        // even though those do not make sense for this patheffect
+        SkRegion clip(ir);
+        
+        this->begin(ir, dst);
+        SkScan::FillPath(tmp, clip, &blitter);
+        this->end(dst);
+    }
+    return true;
+}
+
+void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path)
+{
+    const SkMatrix& mat = this->getMatrix();
+    SkPoint src, dst;
+
+    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
+    do {
+        mat.mapPoints(&dst, &src, 1);
+        this->next(dst, x++, y, path);
+        src.fX += SK_Scalar1;
+    } while (--count > 0);
+}
+
+void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
+void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
+void Sk2DPathEffect::end(SkPath* dst) {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer)
+{
+    buffer.writeMul4(&fMatrix, sizeof(fMatrix));
+}
+
+Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer)
+{
+    buffer.read(&fMatrix, sizeof(fMatrix));
+    fMatrix.invert(&fInverse);
+}
+
+SkFlattenable::Factory Sk2DPathEffect::getFactory()
+{
+    return CreateProc;
+}
+
+SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer)
+{
+    return SkNEW_ARGS(Sk2DPathEffect, (buffer));
+}
+
+
+