Sk2DPathEffect.cpp revision d26147adbbdca85f07dff432025afee0c8614387
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 this->begin(ir, dst); 43 SkScan::FillPath(tmp, ir, &blitter); 44 this->end(dst); 45 } 46 return true; 47} 48 49void 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 61void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} 62void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} 63void Sk2DPathEffect::end(SkPath* dst) {} 64 65/////////////////////////////////////////////////////////////////////////////// 66 67void 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 74Sk2DPathEffect::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 83SkFlattenable::Factory Sk2DPathEffect::getFactory() { 84 return CreateProc; 85} 86 87SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 88 return SkNEW_ARGS(Sk2DPathEffect, (buffer)); 89} 90 91/////////////////////////////////////////////////////////////////////////////// 92/////////////////////////////////////////////////////////////////////////////// 93 94SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 95 : INHERITED(m), fPath(p) { 96} 97 98SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer) 99 : INHERITED(buffer) { 100 fPath.unflatten(buffer); 101} 102 103SkFlattenable* SkPath2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 104 return SkNEW_ARGS(SkPath2DPathEffect, (buffer)); 105} 106 107void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 108 this->INHERITED::flatten(buffer); 109 fPath.flatten(buffer); 110} 111 112SkFlattenable::Factory SkPath2DPathEffect::getFactory() { 113 return CreateProc; 114} 115 116void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) { 117 dst->addPath(fPath, loc.fX, loc.fY); 118} 119 120SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect) 121 122