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