Sk2DPathEffect.cpp revision 16edff2b1cbd80e36456138f8631711a585205ba
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 mat.invert(&fInverse); 32} 33 34bool 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 // need to pass a clip to fillpath, required for inverse filltypes, 43 // even though those do not make sense for this patheffect 44 SkRegion clip(ir); 45 46 this->begin(ir, dst); 47 SkScan::FillPath(tmp, clip, &blitter); 48 this->end(dst); 49 } 50 return true; 51} 52 53void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) { 54 const SkMatrix& mat = this->getMatrix(); 55 SkPoint src, dst; 56 57 src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf); 58 do { 59 mat.mapPoints(&dst, &src, 1); 60 this->next(dst, x++, y, path); 61 src.fX += SK_Scalar1; 62 } while (--count > 0); 63} 64 65void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} 66void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} 67void Sk2DPathEffect::end(SkPath* dst) {} 68 69/////////////////////////////////////////////////////////////////////////////// 70 71void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 72 char storage[SkMatrix::kMaxFlattenSize]; 73 uint32_t size = fMatrix.flatten(storage); 74 buffer.write32(size); 75 buffer.write(storage, size); 76} 77 78Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) { 79 char storage[SkMatrix::kMaxFlattenSize]; 80 uint32_t size = buffer.readS32(); 81 SkASSERT(size <= sizeof(storage)); 82 buffer.read(storage, size); 83 fMatrix.unflatten(storage); 84 fMatrix.invert(&fInverse); 85} 86 87SkFlattenable::Factory Sk2DPathEffect::getFactory() { 88 return CreateProc; 89} 90 91SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 92 return SkNEW_ARGS(Sk2DPathEffect, (buffer)); 93} 94 95/////////////////////////////////////////////////////////////////////////////// 96/////////////////////////////////////////////////////////////////////////////// 97 98SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 99 : INHERITED(m), fPath(p) { 100} 101 102SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer) 103 : INHERITED(buffer) { 104 fPath.unflatten(buffer); 105} 106 107SkFlattenable* SkPath2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 108 return SkNEW_ARGS(SkPath2DPathEffect, (buffer)); 109} 110 111void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 112 this->INHERITED::flatten(buffer); 113 fPath.flatten(buffer); 114} 115 116SkFlattenable::Factory SkPath2DPathEffect::getFactory() { 117 return CreateProc; 118} 119 120void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) { 121 dst->addPath(fPath, loc.fX, loc.fY); 122} 123 124static SkFlattenable::Registrar gReg("SkPath2DPathEffect", 125 SkPath2DPathEffect::CreateProc); 126 127