180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBoundaryPatch.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBoundaryPatch::SkBoundaryPatch() : fBoundary(NULL) {}
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBoundaryPatch::~SkBoundaryPatch() {
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fBoundary);
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBoundary* SkBoundaryPatch::setBoundary(SkBoundary* b) {
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRefCnt_SafeAssign(fBoundary, b);
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return b;
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPoint SkMakePoint(SkScalar x, SkScalar y) {
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint pt;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pt.set(x, y);
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return pt;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkMakePoint(SkScalarInterp(a.fX, b.fX, t),
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                       SkScalarInterp(a.fY, b.fY, t));
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPoint SkBoundaryPatch::eval(SkScalar unitU, SkScalar unitV) {
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBoundary* b = fBoundary;
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint u = SkPointInterp(b->eval(SkBoundary::kLeft, SK_Scalar1 - unitV),
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              b->eval(SkBoundary::kRight, unitV),
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              unitU);
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint v = SkPointInterp(b->eval(SkBoundary::kTop, unitU),
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              b->eval(SkBoundary::kBottom, SK_Scalar1 - unitU),
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              unitV);
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkMakePoint(SkScalarAve(u.fX, v.fX),
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                       SkScalarAve(u.fY, v.fY));
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkBoundaryPatch::evalPatch(SkPoint verts[], int rows, int cols) {
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (rows < 2 || cols < 2) {
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkScalar invR = SkScalarInvert(SkIntToScalar(rows - 1));
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkScalar invC = SkScalarInvert(SkIntToScalar(cols - 1));
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int y = 0; y < cols; y++) {
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar yy = y * invC;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int x = 0; x < rows; x++) {
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *verts++ = this->eval(x * invR, yy);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGeometry.h"
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPoint SkLineBoundary::eval(Edge e, SkScalar t) {
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)e < 4);
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPointInterp(fPts[e], fPts[(e + 1) & 3], t);
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPoint SkCubicBoundary::eval(Edge e, SkScalar t) {
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)e < 4);
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // ensure our 4th cubic wraps to the start of the first
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPts[12] = fPts[0];
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint loc;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkEvalCubicAt(&fPts[e * 3], t, &loc, NULL, NULL);
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return loc;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
80