1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "Sk2DPathEffect.h" 11 #include "SkBlitter.h" 12 #include "SkPath.h" 13 #include "SkScan.h" 14 15 class Sk2DPathEffectBlitter : public SkBlitter { 16 public: 17 Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst) 18 : fPE(pe), fDst(dst) {} 19 20 virtual void blitH(int x, int y, int count) { 21 fPE->nextSpan(x, y, count, fDst); 22 } 23 private: 24 Sk2DPathEffect* fPE; 25 SkPath* fDst; 26 }; 27 28 /////////////////////////////////////////////////////////////////////////////// 29 30 Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) { 31 mat.invert(&fInverse); 32 } 33 34 bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) { 35 Sk2DPathEffectBlitter blitter(this, dst); 36 SkPath tmp; 37 SkIRect ir; 38 39 src.transform(fInverse, &tmp); 40 tmp.getBounds().round(&ir); 41 if (!ir.isEmpty()) { 42 this->begin(ir, dst); 43 SkScan::FillPath(tmp, ir, &blitter); 44 this->end(dst); 45 } 46 return true; 47 } 48 49 void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) { 50 const SkMatrix& mat = this->getMatrix(); 51 SkPoint src, dst; 52 53 src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf); 54 do { 55 mat.mapPoints(&dst, &src, 1); 56 this->next(dst, x++, y, path); 57 src.fX += SK_Scalar1; 58 } while (--count > 0); 59 } 60 61 void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} 62 void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} 63 void Sk2DPathEffect::end(SkPath* dst) {} 64 65 /////////////////////////////////////////////////////////////////////////////// 66 67 void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 68 char storage[SkMatrix::kMaxFlattenSize]; 69 uint32_t size = fMatrix.flatten(storage); 70 buffer.write32(size); 71 buffer.write(storage, size); 72 } 73 74 Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) { 75 char storage[SkMatrix::kMaxFlattenSize]; 76 uint32_t size = buffer.readS32(); 77 SkASSERT(size <= sizeof(storage)); 78 buffer.read(storage, size); 79 fMatrix.unflatten(storage); 80 fMatrix.invert(&fInverse); 81 } 82 83 SkFlattenable::Factory Sk2DPathEffect::getFactory() { 84 return CreateProc; 85 } 86 87 SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 88 return SkNEW_ARGS(Sk2DPathEffect, (buffer)); 89 } 90 91 /////////////////////////////////////////////////////////////////////////////// 92 /////////////////////////////////////////////////////////////////////////////// 93 94 SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 95 : INHERITED(m), fPath(p) { 96 } 97 98 SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer) 99 : INHERITED(buffer) { 100 fPath.unflatten(buffer); 101 } 102 103 SkFlattenable* SkPath2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 104 return SkNEW_ARGS(SkPath2DPathEffect, (buffer)); 105 } 106 107 void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 108 this->INHERITED::flatten(buffer); 109 fPath.flatten(buffer); 110 } 111 112 SkFlattenable::Factory SkPath2DPathEffect::getFactory() { 113 return CreateProc; 114 } 115 116 void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) { 117 dst->addPath(fPath, loc.fX, loc.fY); 118 } 119 120 SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect) 121 122