Sk2DPathEffect.cpp revision d8a6cc814f1a0a8faaddad05ae765ad2f6b11aac
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 "SkFlattenableBuffers.h" 12#include "SkPath.h" 13#include "SkRegion.h" 14 15Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) { 16 fMatrixIsInvertible = mat.invert(&fInverse); 17} 18 19bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) { 20 if (!fMatrixIsInvertible) { 21 return false; 22 } 23 24 SkPath tmp; 25 SkIRect ir; 26 27 src.transform(fInverse, &tmp); 28 tmp.getBounds().round(&ir); 29 if (!ir.isEmpty()) { 30 this->begin(ir, dst); 31 32 SkRegion rgn; 33 rgn.setPath(tmp, SkRegion(ir)); 34 SkRegion::Iterator iter(rgn); 35 for (; !iter.done(); iter.next()) { 36 const SkIRect& rect = iter.rect(); 37 for (int y = rect.fTop; y < rect.fBottom; ++y) { 38 this->nextSpan(rect.fLeft, y, rect.width(), dst); 39 } 40 } 41 42 this->end(dst); 43 } 44 return true; 45} 46 47void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) { 48 if (!fMatrixIsInvertible) { 49 return; 50 } 51 52 const SkMatrix& mat = this->getMatrix(); 53 SkPoint src, dst; 54 55 src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf); 56 do { 57 mat.mapPoints(&dst, &src, 1); 58 this->next(dst, x++, y, path); 59 src.fX += SK_Scalar1; 60 } while (--count > 0); 61} 62 63void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} 64void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} 65void Sk2DPathEffect::end(SkPath* dst) {} 66 67/////////////////////////////////////////////////////////////////////////////// 68 69void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 70 this->INHERITED::flatten(buffer); 71 buffer.writeMatrix(fMatrix); 72} 73 74Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) { 75 buffer.readMatrix(&fMatrix); 76 fMatrixIsInvertible = fMatrix.invert(&fInverse); 77} 78 79SK_DEFINE_FLATTENABLE_REGISTRAR(Sk2DPathEffect) 80 81/////////////////////////////////////////////////////////////////////////////// 82 83bool SkLine2DPathEffect::filterPath(SkPath *dst, const SkPath &src, SkStrokeRec *rec) { 84 if (this->INHERITED::filterPath(dst, src, rec)) { 85 rec->setStrokeStyle(fWidth); 86 return true; 87 } 88 return false; 89} 90 91void SkLine2DPathEffect::nextSpan(int u, int v, int ucount, SkPath *dst) { 92 if (ucount > 1) { 93 SkPoint src[2], dstP[2]; 94 95 src[0].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf); 96 src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf); 97 this->getMatrix().mapPoints(dstP, src, 2); 98 99 dst->moveTo(dstP[0]); 100 dst->lineTo(dstP[1]); 101 } 102} 103 104SkLine2DPathEffect::SkLine2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { 105 fWidth = buffer.readScalar(); 106} 107 108void SkLine2DPathEffect::flatten(SkFlattenableWriteBuffer &buffer) const { 109 this->INHERITED::flatten(buffer); 110 buffer.writeScalar(fWidth); 111} 112 113SK_DEFINE_FLATTENABLE_REGISTRAR(SkLine2DPathEffect) 114 115/////////////////////////////////////////////////////////////////////////////// 116 117SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 118 : INHERITED(m), fPath(p) { 119} 120 121SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer) 122 : INHERITED(buffer) { 123 buffer.readPath(&fPath); 124} 125 126void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 127 this->INHERITED::flatten(buffer); 128 buffer.writePath(fPath); 129} 130 131void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) { 132 dst->addPath(fPath, loc.fX, loc.fY); 133} 134 135/////////////////////////////////////////////////////////////////////////////// 136 137SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect) 138