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