Sk2DPathEffect.cpp revision 90bf427001fd4f6d9fcee88911deb015aeb4ab7c
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 15class Sk2DPathEffectBlitter : public SkBlitter { 16public: 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 } 23private: 24 Sk2DPathEffect* fPE; 25 SkPath* fDst; 26}; 27 28/////////////////////////////////////////////////////////////////////////////// 29 30Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) { 31 fMatrixIsInvertible = mat.invert(&fInverse); 32} 33 34bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) { 35 if (!fMatrixIsInvertible) { 36 return false; 37 } 38 39 Sk2DPathEffectBlitter blitter(this, dst); 40 SkPath tmp; 41 SkIRect ir; 42 43 src.transform(fInverse, &tmp); 44 tmp.getBounds().round(&ir); 45 if (!ir.isEmpty()) { 46 this->begin(ir, dst); 47 SkScan::FillPath(tmp, ir, &blitter); 48 this->end(dst); 49 } 50 return true; 51} 52 53void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) { 54 if (!fMatrixIsInvertible) { 55 return; 56 } 57 58 const SkMatrix& mat = this->getMatrix(); 59 SkPoint src, dst; 60 61 src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf); 62 do { 63 mat.mapPoints(&dst, &src, 1); 64 this->next(dst, x++, y, path); 65 src.fX += SK_Scalar1; 66 } while (--count > 0); 67} 68 69void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} 70void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} 71void Sk2DPathEffect::end(SkPath* dst) {} 72 73/////////////////////////////////////////////////////////////////////////////// 74 75void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 76 this->INHERITED::flatten(buffer); 77 char storage[SkMatrix::kMaxFlattenSize]; 78 uint32_t size = fMatrix.flatten(storage); 79 buffer.write32(size); 80 buffer.write(storage, size); 81} 82 83Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) { 84 char storage[SkMatrix::kMaxFlattenSize]; 85 uint32_t size = buffer.readS32(); 86 SkASSERT(size <= sizeof(storage)); 87 buffer.read(storage, size); 88 fMatrix.unflatten(storage); 89 fMatrixIsInvertible = fMatrix.invert(&fInverse); 90} 91 92/////////////////////////////////////////////////////////////////////////////// 93/////////////////////////////////////////////////////////////////////////////// 94 95SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 96 : INHERITED(m), fPath(p) { 97} 98 99SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer) 100 : INHERITED(buffer) { 101 buffer.readPath(&fPath); 102} 103 104void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 105 this->INHERITED::flatten(buffer); 106 buffer.writePath(fPath); 107} 108 109void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) { 110 dst->addPath(fPath, loc.fX, loc.fY); 111} 112 113/////////////////////////////////////////////////////////////////////////////// 114 115SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect) 116