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 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 77 Sk2DPathEffect::Sk2DPathEffect(SkReadBuffer& buffer) { 78 buffer.readMatrix(&fMatrix); 79 fMatrixIsInvertible = fMatrix.invert(&fInverse); 80 } 81 #endif 82 83 /////////////////////////////////////////////////////////////////////////////// 84 85 bool SkLine2DPathEffect::filterPath(SkPath* dst, const SkPath& src, 86 SkStrokeRec* rec, const SkRect* cullRect) const { 87 if (this->INHERITED::filterPath(dst, src, rec, cullRect)) { 88 rec->setStrokeStyle(fWidth); 89 return true; 90 } 91 return false; 92 } 93 94 void SkLine2DPathEffect::nextSpan(int u, int v, int ucount, SkPath* dst) const { 95 if (ucount > 1) { 96 SkPoint src[2], dstP[2]; 97 98 src[0].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf); 99 src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf); 100 this->getMatrix().mapPoints(dstP, src, 2); 101 102 dst->moveTo(dstP[0]); 103 dst->lineTo(dstP[1]); 104 } 105 } 106 107 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 108 SkLine2DPathEffect::SkLine2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { 109 fWidth = buffer.readScalar(); 110 } 111 #endif 112 113 SkFlattenable* SkLine2DPathEffect::CreateProc(SkReadBuffer& buffer) { 114 SkMatrix matrix; 115 buffer.readMatrix(&matrix); 116 SkScalar width = buffer.readScalar(); 117 return SkLine2DPathEffect::Create(width, matrix); 118 } 119 120 void SkLine2DPathEffect::flatten(SkWriteBuffer &buffer) const { 121 buffer.writeMatrix(this->getMatrix()); 122 buffer.writeScalar(fWidth); 123 } 124 125 /////////////////////////////////////////////////////////////////////////////// 126 127 SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 128 : INHERITED(m), fPath(p) { 129 } 130 131 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 132 SkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { 133 buffer.readPath(&fPath); 134 } 135 #endif 136 137 SkFlattenable* SkPath2DPathEffect::CreateProc(SkReadBuffer& buffer) { 138 SkMatrix matrix; 139 buffer.readMatrix(&matrix); 140 SkPath path; 141 buffer.readPath(&path); 142 return SkPath2DPathEffect::Create(matrix, path); 143 } 144 145 void SkPath2DPathEffect::flatten(SkWriteBuffer& buffer) const { 146 buffer.writeMatrix(this->getMatrix()); 147 buffer.writePath(fPath); 148 } 149 150 void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, 151 SkPath* dst) const { 152 dst->addPath(fPath, loc.fX, loc.fY); 153 } 154