1 #include "SkBoundaryPatch.h" 2 3 SkBoundaryPatch::SkBoundaryPatch() : fBoundary(NULL) {} 4 5 SkBoundaryPatch::~SkBoundaryPatch() { 6 SkSafeUnref(fBoundary); 7 } 8 9 SkBoundary* SkBoundaryPatch::setBoundary(SkBoundary* b) { 10 SkRefCnt_SafeAssign(fBoundary, b); 11 return b; 12 } 13 14 static SkPoint SkMakePoint(SkScalar x, SkScalar y) { 15 SkPoint pt; 16 pt.set(x, y); 17 return pt; 18 } 19 20 static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) { 21 return SkMakePoint(SkScalarInterp(a.fX, b.fX, t), 22 SkScalarInterp(a.fY, b.fY, t)); 23 } 24 25 SkPoint SkBoundaryPatch::eval(SkScalar unitU, SkScalar unitV) { 26 SkBoundary* b = fBoundary; 27 SkPoint u = SkPointInterp(b->eval(SkBoundary::kLeft, SK_Scalar1 - unitV), 28 b->eval(SkBoundary::kRight, unitV), 29 unitU); 30 SkPoint v = SkPointInterp(b->eval(SkBoundary::kTop, unitU), 31 b->eval(SkBoundary::kBottom, SK_Scalar1 - unitU), 32 unitV); 33 return SkMakePoint(SkScalarAve(u.fX, v.fX), 34 SkScalarAve(u.fY, v.fY)); 35 } 36 37 bool SkBoundaryPatch::evalPatch(SkPoint verts[], int rows, int cols) { 38 if (rows < 2 || cols < 2) { 39 return false; 40 } 41 42 const SkScalar invR = SkScalarInvert(SkIntToScalar(rows - 1)); 43 const SkScalar invC = SkScalarInvert(SkIntToScalar(cols - 1)); 44 45 for (int y = 0; y < cols; y++) { 46 SkScalar yy = y * invC; 47 for (int x = 0; x < rows; x++) { 48 *verts++ = this->eval(x * invR, yy); 49 } 50 } 51 return true; 52 } 53 54 //////////////////////////////////////////////////////////////////////// 55 56 #include "SkGeometry.h" 57 58 SkPoint SkLineBoundary::eval(Edge e, SkScalar t) { 59 SkASSERT((unsigned)e < 4); 60 return SkPointInterp(fPts[e], fPts[(e + 1) & 3], t); 61 } 62 63 SkPoint SkCubicBoundary::eval(Edge e, SkScalar t) { 64 SkASSERT((unsigned)e < 4); 65 66 // ensure our 4th cubic wraps to the start of the first 67 fPts[12] = fPts[0]; 68 69 SkPoint loc; 70 SkEvalCubicAt(&fPts[e * 3], t, &loc, NULL, NULL); 71 return loc; 72 } 73 74