1 /* libs/graphics/effects/Sk2DPathEffect.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "Sk2DPathEffect.h"
19 #include "SkBlitter.h"
20 #include "SkPath.h"
21 #include "SkScan.h"
22
23 class Sk2DPathEffectBlitter : public SkBlitter {
24 public:
Sk2DPathEffectBlitter(Sk2DPathEffect * pe,SkPath * dst)25 Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst)
26 : fPE(pe), fDst(dst)
27 {}
blitH(int x,int y,int count)28 virtual void blitH(int x, int y, int count)
29 {
30 fPE->nextSpan(x, y, count, fDst);
31 }
32 private:
33 Sk2DPathEffect* fPE;
34 SkPath* fDst;
35 };
36
37 ////////////////////////////////////////////////////////////////////////////////////
38
Sk2DPathEffect(const SkMatrix & mat)39 Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat)
40 {
41 mat.invert(&fInverse);
42 }
43
filterPath(SkPath * dst,const SkPath & src,SkScalar * width)44 bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width)
45 {
46 Sk2DPathEffectBlitter blitter(this, dst);
47 SkPath tmp;
48 SkIRect ir;
49
50 src.transform(fInverse, &tmp);
51 tmp.getBounds().round(&ir);
52 if (!ir.isEmpty()) {
53 // need to pass a clip to fillpath, required for inverse filltypes,
54 // even though those do not make sense for this patheffect
55 SkRegion clip(ir);
56
57 this->begin(ir, dst);
58 SkScan::FillPath(tmp, clip, &blitter);
59 this->end(dst);
60 }
61 return true;
62 }
63
nextSpan(int x,int y,int count,SkPath * path)64 void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path)
65 {
66 const SkMatrix& mat = this->getMatrix();
67 SkPoint src, dst;
68
69 src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
70 do {
71 mat.mapPoints(&dst, &src, 1);
72 this->next(dst, x++, y, path);
73 src.fX += SK_Scalar1;
74 } while (--count > 0);
75 }
76
begin(const SkIRect & uvBounds,SkPath * dst)77 void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
next(const SkPoint & loc,int u,int v,SkPath * dst)78 void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
end(SkPath * dst)79 void Sk2DPathEffect::end(SkPath* dst) {}
80
81 ////////////////////////////////////////////////////////////////////////////////
82
flatten(SkFlattenableWriteBuffer & buffer)83 void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer)
84 {
85 buffer.writeMul4(&fMatrix, sizeof(fMatrix));
86 }
87
Sk2DPathEffect(SkFlattenableReadBuffer & buffer)88 Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer)
89 {
90 buffer.read(&fMatrix, sizeof(fMatrix));
91 fMatrix.invert(&fInverse);
92 }
93
getFactory()94 SkFlattenable::Factory Sk2DPathEffect::getFactory()
95 {
96 return CreateProc;
97 }
98
CreateProc(SkFlattenableReadBuffer & buffer)99 SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer)
100 {
101 return SkNEW_ARGS(Sk2DPathEffect, (buffer));
102 }
103
104
105
106