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: 25 Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst) 26 : fPE(pe), fDst(dst) 27 {} 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 39 Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) 40 { 41 mat.invert(&fInverse); 42 } 43 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 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 77 void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} 78 void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} 79 void Sk2DPathEffect::end(SkPath* dst) {} 80 81 //////////////////////////////////////////////////////////////////////////////// 82 83 void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) 84 { 85 char storage[SkMatrix::kMaxFlattenSize]; 86 uint32_t size = fMatrix.flatten(storage); 87 buffer.write32(size); 88 buffer.write(storage, size); 89 } 90 91 Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) 92 { 93 char storage[SkMatrix::kMaxFlattenSize]; 94 uint32_t size = buffer.readS32(); 95 SkASSERT(size <= sizeof(storage)); 96 buffer.read(storage, size); 97 fMatrix.unflatten(storage); 98 fMatrix.invert(&fInverse); 99 } 100 101 SkFlattenable::Factory Sk2DPathEffect::getFactory() 102 { 103 return CreateProc; 104 } 105 106 SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) 107 { 108 return SkNEW_ARGS(Sk2DPathEffect, (buffer)); 109 } 110 111 112 113