11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 83798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed#include "SkBoundaryPatch.h" 93798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 103798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkBoundaryPatch::SkBoundaryPatch() : fBoundary(NULL) {} 113798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 123798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkBoundaryPatch::~SkBoundaryPatch() { 133798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkSafeUnref(fBoundary); 143798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 153798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 163798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkBoundary* SkBoundaryPatch::setBoundary(SkBoundary* b) { 173798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkRefCnt_SafeAssign(fBoundary, b); 183798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return b; 193798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 203798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 213798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reedstatic SkPoint SkMakePoint(SkScalar x, SkScalar y) { 223798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkPoint pt; 233798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed pt.set(x, y); 243798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return pt; 253798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 263798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 273798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reedstatic SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) { 283798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return SkMakePoint(SkScalarInterp(a.fX, b.fX, t), 293798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkScalarInterp(a.fY, b.fY, t)); 303798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 313798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 323798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkPoint SkBoundaryPatch::eval(SkScalar unitU, SkScalar unitV) { 333798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkBoundary* b = fBoundary; 343798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkPoint u = SkPointInterp(b->eval(SkBoundary::kLeft, SK_Scalar1 - unitV), 353798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed b->eval(SkBoundary::kRight, unitV), 363798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed unitU); 373798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkPoint v = SkPointInterp(b->eval(SkBoundary::kTop, unitU), 383798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed b->eval(SkBoundary::kBottom, SK_Scalar1 - unitU), 393798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed unitV); 403798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return SkMakePoint(SkScalarAve(u.fX, v.fX), 413798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkScalarAve(u.fY, v.fY)); 423798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 433798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 443798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reedbool SkBoundaryPatch::evalPatch(SkPoint verts[], int rows, int cols) { 453798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed if (rows < 2 || cols < 2) { 463798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return false; 473798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed } 483798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 493798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed const SkScalar invR = SkScalarInvert(SkIntToScalar(rows - 1)); 503798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed const SkScalar invC = SkScalarInvert(SkIntToScalar(cols - 1)); 513798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 523798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed for (int y = 0; y < cols; y++) { 533798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkScalar yy = y * invC; 543798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed for (int x = 0; x < rows; x++) { 553798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed *verts++ = this->eval(x * invR, yy); 563798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed } 573798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed } 583798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return true; 593798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 603798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 613798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed//////////////////////////////////////////////////////////////////////// 623798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 633798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed#include "SkGeometry.h" 643798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 653798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkPoint SkLineBoundary::eval(Edge e, SkScalar t) { 663798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkASSERT((unsigned)e < 4); 673798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return SkPointInterp(fPts[e], fPts[(e + 1) & 3], t); 683798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 693798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 703798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkPoint SkCubicBoundary::eval(Edge e, SkScalar t) { 713798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkASSERT((unsigned)e < 4); 723798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 733798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed // ensure our 4th cubic wraps to the start of the first 743798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed fPts[12] = fPts[0]; 753798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 763798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkPoint loc; 773798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed SkEvalCubicAt(&fPts[e * 3], t, &loc, NULL, NULL); 783798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed return loc; 793798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed} 803798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed 81