| Index: src/core/SkPatch.cpp
|
| diff --git a/src/core/SkPatch.cpp b/src/core/SkPatch.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..23ec4c2e4155920a78a4eb178c3fd39fb06cdf4e
|
| --- /dev/null
|
| +++ b/src/core/SkPatch.cpp
|
| @@ -0,0 +1,188 @@
|
| +/*
|
| + * Copyright 2014 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkPatch.h"
|
| +
|
| +#include "SkGeometry.h"
|
| +#include "SkGr.h"
|
| +
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SkFwDCubicEvaluator::SkFwDCubicEvaluator(SkPoint a, SkPoint b, SkPoint c, SkPoint d){
|
| + fPoints[0] = a;
|
| + fPoints[1] = b;
|
| + fPoints[2] = c;
|
| + fPoints[3] = d;
|
| +
|
| + SkScalar cx[4], cy[4];
|
| + SkGetCubicCoeff(fPoints, cx, cy);
|
| + fCoefs[0].set(cx[0], cy[0]);
|
| + fCoefs[1].set(cx[1], cy[1]);
|
| + fCoefs[2].set(cx[2], cy[2]);
|
| + fCoefs[3].set(cx[3], cy[3]);
|
| +
|
| + this->reset(1);
|
| +}
|
| +
|
| +void SkFwDCubicEvaluator::reset(int res){
|
| + fRes = res;
|
| + SkScalar h = 1.f/res;
|
| + fCurrent = 0;
|
| + fMax = res + 1;
|
| + fFwDiff[0] = fCoefs[3];
|
| + SkScalar h2 = h*h;
|
| + SkScalar h3 = h2*h;
|
| +
|
| + fFwDiff[3].set(6.f*fCoefs[0].x()*h3, 6.f*fCoefs[0].y()*h3); //6ah^3
|
| + fFwDiff[2].set(fFwDiff[3].x() + 2.f*fCoefs[1].x()*h2, //6ah^3 + 2bh^2
|
| + fFwDiff[3].y() + 2.f*fCoefs[1].y()*h2);
|
| + fFwDiff[1].set(fCoefs[0].x()*h3 + fCoefs[1].x()*h2 + fCoefs[2].x()*h, //ah^3 + bh^2 + ch
|
| + fCoefs[0].y()*h3 + fCoefs[1].y()*h2 + fCoefs[2].y()*h);
|
| +}
|
| +
|
| +const SkPoint* SkFwDCubicEvaluator::getPoints() {
|
| + return fPoints;
|
| +}
|
| +
|
| +const SkPoint* SkFwDCubicEvaluator::getCoefs() {
|
| + return fCoefs;
|
| +}
|
| +
|
| +int SkFwDCubicEvaluator::getResolution() {
|
| + return fRes;
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SkPatch::SkPatch(SkPoint points[12], SkColor (*colors)[4], int res)
|
| + : fCtrlPoints(points)
|
| + , fBottom(points[0], points[1], points[2], points[3])
|
| + , fTop(points[4], points[5], points[6], points[7])
|
| + , fLeft(points[0], points[8], points[9], points[4])
|
| + , fRight(points[3], points[10], points[11], points[7])
|
| + , fResX(res)
|
| + , fResY(res)
|
| + , fVertCount(0)
|
| + , fIndexCount(0)
|
| + , fPoints(NULL)
|
| + , fTexCoords(NULL)
|
| + , fColors(NULL)
|
| + , fIndices(NULL)
|
| + , fIsSet(false) {
|
| + fCornerColors[0] = SkPreMultiplyColor((*colors)[0]);
|
| + fCornerColors[1] = SkPreMultiplyColor((*colors)[1]);
|
| + fCornerColors[2] = SkPreMultiplyColor((*colors)[2]);
|
| + fCornerColors[3] = SkPreMultiplyColor((*colors)[3]);
|
| +}
|
| +
|
| +void SkPatch::clean() {
|
| + SkDELETE_ARRAY (fPoints);
|
| + SkDELETE_ARRAY (fTexCoords);
|
| + SkDELETE_ARRAY (fColors);
|
| + SkDELETE_ARRAY (fIndices);
|
| + fVertCount = 0;
|
| + fIndexCount = 0;
|
| + fPoints = NULL;
|
| + fTexCoords = NULL;
|
| + fColors = NULL;
|
| + fIndices = NULL;
|
| + fIsSet = false;
|
| +}
|
| +
|
| +SkPatch::~SkPatch() {
|
| + this->clean();
|
| +}
|
| +
|
| +uint8_t bilinear(SkScalar tx, SkScalar ty, SkScalar c00, SkScalar c10, SkScalar c01, SkScalar c11) {
|
| + SkScalar a = c00 * (1.f - tx) + c10 * tx;
|
| + SkScalar b = c01 * (1.f - tx) + c11 * tx;
|
| + return uint8_t(a * (1.f - ty) + b * ty);
|
| +}
|
| +
|
| +void SkPatch::setData() {
|
| +
|
| + if (fIsSet) {
|
| + return;
|
| + }
|
| +
|
| + fIsSet = true;
|
| + fVertCount = (fResX + 1) * (fResY + 1);
|
| + fIndexCount = fResX * fResY * 6;
|
| +
|
| + fPoints = SkNEW_ARRAY(SkPoint, fVertCount);
|
| + fColors = SkNEW_ARRAY(uint32_t, fVertCount);
|
| + fTexCoords = SkNEW_ARRAY(SkPoint, fVertCount);
|
| + fIndices = SkNEW_ARRAY(uint16_t, fIndexCount);
|
| +
|
| + fBottom.reset(fResX);
|
| + fTop.reset(fResX);
|
| +
|
| + SkScalar u = 0.0f;
|
| + int stride = fResY+1;
|
| + for (int x = 0; x <= fResX; x++) {
|
| + SkPoint bottom = fBottom++, top = fTop++;
|
| + fLeft.reset(fResY);
|
| + fRight.reset(fResY);
|
| + SkScalar v = 0.f;
|
| + for (int y = 0; y <= fResY; y++) {
|
| + int dataIndex = x*(fResX + 1) + y;
|
| +
|
| + SkPoint left = fLeft++, right = fRight++;
|
| +
|
| + SkPoint s0 = SkPoint::Make((1.0f - v)*bottom.x() + v*top.x(),
|
| + (1.0f - v)*bottom.y() + v*top.y());
|
| + SkPoint s1 = SkPoint::Make((1.0f - u)*left.x() + u*right.x(),
|
| + (1.0f - u)*left.y() + u*right.y());
|
| + SkPoint s2 = SkPoint::Make(
|
| + (1.0f - v)*((1.0f - u)*fBottom.getPoints()[0].x()
|
| + + u*fBottom.getPoints()[3].x())
|
| + + v*((1.0f - u)*fTop.getPoints()[0].x() + u*fTop.getPoints()[3].x()),
|
| + (1.0f - v)*((1.0f - u)*fBottom.getPoints()[0].y()
|
| + + u*fBottom.getPoints()[3].y())
|
| + + v*((1.0f - u)*fTop.getPoints()[0].y() + u*fTop.getPoints()[3].y()));
|
| + fPoints[dataIndex] = s0 + s1 - s2;
|
| +
|
| + uint8_t a = bilinear(u, v,
|
| + SkScalar(SkColorGetA(fCornerColors[0])),
|
| + SkScalar(SkColorGetA(fCornerColors[1])),
|
| + SkScalar(SkColorGetA(fCornerColors[2])),
|
| + SkScalar(SkColorGetA(fCornerColors[3])));
|
| + uint8_t r = bilinear(u, v,
|
| + SkScalar(SkColorGetR(fCornerColors[0])),
|
| + SkScalar(SkColorGetR(fCornerColors[1])),
|
| + SkScalar(SkColorGetR(fCornerColors[2])),
|
| + SkScalar(SkColorGetR(fCornerColors[3])));
|
| + uint8_t g = bilinear(u, v,
|
| + SkScalar(SkColorGetG(fCornerColors[0])),
|
| + SkScalar(SkColorGetG(fCornerColors[1])),
|
| + SkScalar(SkColorGetG(fCornerColors[2])),
|
| + SkScalar(SkColorGetG(fCornerColors[3])));
|
| + uint8_t b = bilinear(u, v,
|
| + SkScalar(SkColorGetB(fCornerColors[0])),
|
| + SkScalar(SkColorGetB(fCornerColors[1])),
|
| + SkScalar(SkColorGetB(fCornerColors[2])),
|
| + SkScalar(SkColorGetB(fCornerColors[3])));
|
| + fColors[dataIndex] = SkPackARGB32(a,r,g,b);
|
| +
|
| +
|
| + fTexCoords[dataIndex] = SkPoint::Make(u, v);
|
| +
|
| + if(x < fResX && y < fResY) {
|
| + int i = 6*(x*fResY + y);
|
| + fIndices[i] = x*stride+y;
|
| + fIndices[i+1] = x*stride+1+y;
|
| + fIndices[i+2] = (x+1)*stride+1+y;
|
| + fIndices[i+3] = fIndices[i];
|
| + fIndices[i+4] = fIndices[i+2];
|
| + fIndices[i+5] = (x+1)*stride+y;
|
| + }
|
| + v+=1.f/fResY;
|
| + }
|
| + u+=1.f/fResX;
|
| + }
|
| +}
|
|
|