зеркало из https://github.com/mozilla/moz-skia.git
update on boundary patches
git-svn-id: http://skia.googlecode.com/svn/trunk@409 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
b577b41c8e
Коммит
2ee7c64015
|
@ -1,20 +1,14 @@
|
|||
#include "SkBoundaryPatch.h"
|
||||
|
||||
SkBoundaryPatch::SkBoundaryPatch() {
|
||||
sk_bzero(fCurve, sizeof(fCurve));
|
||||
};
|
||||
SkBoundaryPatch::SkBoundaryPatch() : fBoundary(NULL) {}
|
||||
|
||||
SkBoundaryPatch::~SkBoundaryPatch() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
SkSafeUnref(fCurve[i]);
|
||||
}
|
||||
SkSafeUnref(fBoundary);
|
||||
}
|
||||
|
||||
SkBoundaryCurve* SkBoundaryPatch::setCurve(Edge e, SkBoundaryCurve* curve) {
|
||||
SkASSERT((unsigned)e < 4);
|
||||
|
||||
SkRefCnt_SafeAssign(fCurve[e], curve);
|
||||
return curve;
|
||||
SkBoundary* SkBoundaryPatch::setBoundary(SkBoundary* b) {
|
||||
SkRefCnt_SafeAssign(fBoundary, b);
|
||||
return b;
|
||||
}
|
||||
|
||||
static SkPoint SkMakePoint(SkScalar x, SkScalar y) {
|
||||
|
@ -28,27 +22,52 @@ static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
|
|||
SkScalarInterp(a.fY, b.fY, t));
|
||||
}
|
||||
|
||||
SkPoint SkBoundaryPatch::evaluate(SkScalar unitU, SkScalar unitV) {
|
||||
SkPoint u = SkPointInterp(fCurve[kLeft]->evaluate(unitV),
|
||||
fCurve[kRight]->evaluate(unitV), unitU);
|
||||
SkPoint v = SkPointInterp(fCurve[kTop]->evaluate(unitU),
|
||||
fCurve[kBottom]->evaluate(unitU), unitV);
|
||||
SkPoint SkBoundaryPatch::eval(SkScalar unitU, SkScalar unitV) {
|
||||
SkBoundary* b = fBoundary;
|
||||
SkPoint u = SkPointInterp(b->eval(SkBoundary::kLeft, SK_Scalar1 - unitV),
|
||||
b->eval(SkBoundary::kRight, unitV),
|
||||
unitU);
|
||||
SkPoint v = SkPointInterp(b->eval(SkBoundary::kTop, unitU),
|
||||
b->eval(SkBoundary::kBottom, SK_Scalar1 - unitU),
|
||||
unitV);
|
||||
return SkMakePoint(SkScalarAve(u.fX, v.fX),
|
||||
SkScalarAve(u.fY, v.fY));
|
||||
}
|
||||
|
||||
bool SkBoundaryPatch::evalPatch(SkPoint verts[], int rows, int cols) {
|
||||
if (rows < 2 || cols < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const SkScalar invR = SkScalarInvert(SkIntToScalar(rows - 1));
|
||||
const SkScalar invC = SkScalarInvert(SkIntToScalar(cols - 1));
|
||||
|
||||
for (int y = 0; y < cols; y++) {
|
||||
SkScalar yy = y * invC;
|
||||
for (int x = 0; x < rows; x++) {
|
||||
*verts++ = this->eval(x * invR, yy);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkGeometry.h"
|
||||
|
||||
SkPoint SkLineBoundaryCurve::evaluate(SkScalar t) {
|
||||
return SkPointInterp(fPts[0], fPts[1], t);
|
||||
SkPoint SkLineBoundary::eval(Edge e, SkScalar t) {
|
||||
SkASSERT((unsigned)e < 4);
|
||||
return SkPointInterp(fPts[e], fPts[(e + 1) & 3], t);
|
||||
}
|
||||
|
||||
SkPoint SkCubicBoundaryCurve::evaluate(SkScalar t) {
|
||||
SkPoint SkCubicBoundary::eval(Edge e, SkScalar t) {
|
||||
SkASSERT((unsigned)e < 4);
|
||||
|
||||
// ensure our 4th cubic wraps to the start of the first
|
||||
fPts[12] = fPts[0];
|
||||
|
||||
SkPoint loc;
|
||||
SkEvalCubicAt(fPts, t, &loc, NULL, NULL);
|
||||
SkEvalCubicAt(&fPts[e * 3], t, &loc, NULL, NULL);
|
||||
return loc;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,9 +4,17 @@
|
|||
#include "SkPoint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkBoundaryCurve : public SkRefCnt {
|
||||
class SkBoundary : public SkRefCnt {
|
||||
public:
|
||||
virtual SkPoint evaluate(SkScalar unitInterval) = 0;
|
||||
// These must be 0, 1, 2, 3 for efficiency in the subclass implementations
|
||||
enum Edge {
|
||||
kTop = 0,
|
||||
kRight = 1,
|
||||
kBottom = 2,
|
||||
kLeft = 3
|
||||
};
|
||||
// Edge index goes clockwise around the boundary, beginning at the "top"
|
||||
virtual SkPoint eval(Edge, SkScalar unitInterval) = 0;
|
||||
};
|
||||
|
||||
class SkBoundaryPatch {
|
||||
|
@ -14,38 +22,33 @@ public:
|
|||
SkBoundaryPatch();
|
||||
~SkBoundaryPatch();
|
||||
|
||||
enum Edge {
|
||||
kLeft,
|
||||
kTop,
|
||||
kRight,
|
||||
kBottom
|
||||
};
|
||||
|
||||
SkBoundaryCurve* getCurve(Edge e) const { return fCurve[e]; }
|
||||
SkBoundaryCurve* setCurve(Edge e, SkBoundaryCurve*);
|
||||
SkBoundary* getBoundary() const { return fBoundary; }
|
||||
SkBoundary* setBoundary(SkBoundary*);
|
||||
|
||||
SkPoint evaluate(SkScalar unitU, SkScalar unitV);
|
||||
SkPoint eval(SkScalar unitU, SkScalar unitV);
|
||||
bool evalPatch(SkPoint verts[], int rows, int cols);
|
||||
|
||||
private:
|
||||
SkBoundaryCurve* fCurve[4];
|
||||
SkBoundary* fBoundary;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkLineBoundaryCurve : public SkBoundaryCurve {
|
||||
public:
|
||||
SkPoint fPts[2];
|
||||
|
||||
// override
|
||||
virtual SkPoint evaluate(SkScalar);
|
||||
};
|
||||
|
||||
class SkCubicBoundaryCurve : public SkBoundaryCurve {
|
||||
class SkLineBoundary : public SkBoundary {
|
||||
public:
|
||||
SkPoint fPts[4];
|
||||
|
||||
// override
|
||||
virtual SkPoint evaluate(SkScalar);
|
||||
virtual SkPoint eval(Edge, SkScalar);
|
||||
};
|
||||
|
||||
class SkCubicBoundary : public SkBoundary {
|
||||
public:
|
||||
// the caller sets the first 12 entries. The 13th is used by the impl.
|
||||
SkPoint fPts[13];
|
||||
|
||||
// override
|
||||
virtual SkPoint eval(Edge, SkScalar);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef SkMeshUtils_DEFINED
|
||||
#define SkMeshUtils_DEFINED
|
||||
|
||||
#include "SkPoint.h"
|
||||
#include "SkColor.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
|
||||
class SkMeshIndices {
|
||||
public:
|
||||
SkMeshIndices();
|
||||
~SkMeshIndices();
|
||||
|
||||
bool init(int texW, int texH, int rows, int cols) {
|
||||
return this->init(NULL, NULL, texW, texH, rows, cols);
|
||||
}
|
||||
|
||||
bool init(SkPoint tex[], uint16_t indices[],
|
||||
int texW, int texH, int rows, int cols);
|
||||
|
||||
size_t indexCount() const { return fIndexCount; }
|
||||
const uint16_t* indices() const { return fIndices; }
|
||||
|
||||
size_t texCount() const { return fTexCount; }
|
||||
const SkPoint* tex() const { return fTex; }
|
||||
|
||||
private:
|
||||
size_t fIndexCount, fTexCount;
|
||||
SkPoint* fTex;
|
||||
uint16_t* fIndices;
|
||||
void* fStorage; // may be null
|
||||
};
|
||||
|
||||
class SkMeshUtils {
|
||||
public:
|
||||
static void Draw(SkCanvas*, const SkBitmap&, int rows, int cols,
|
||||
const SkPoint verts[], const SkColor colors[],
|
||||
const SkPaint& paint);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,6 +5,50 @@
|
|||
#include "SkAnimator.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
#include "SkColorPriv.h"
|
||||
static inline void Filter_32_opaque_portable(unsigned x, unsigned y,
|
||||
SkPMColor a00, SkPMColor a01,
|
||||
SkPMColor a10, SkPMColor a11,
|
||||
SkPMColor* dstColor) {
|
||||
SkASSERT((unsigned)x <= 0xF);
|
||||
SkASSERT((unsigned)y <= 0xF);
|
||||
|
||||
int xy = x * y;
|
||||
uint32_t mask = gMask_00FF00FF; //0xFF00FF;
|
||||
|
||||
int scale = 256 - 16*y - 16*x + xy;
|
||||
uint32_t lo = (a00 & mask) * scale;
|
||||
uint32_t hi = ((a00 >> 8) & mask) * scale;
|
||||
|
||||
scale = 16*x - xy;
|
||||
lo += (a01 & mask) * scale;
|
||||
hi += ((a01 >> 8) & mask) * scale;
|
||||
|
||||
scale = 16*y - xy;
|
||||
lo += (a10 & mask) * scale;
|
||||
hi += ((a10 >> 8) & mask) * scale;
|
||||
|
||||
lo += (a11 & mask) * xy;
|
||||
hi += ((a11 >> 8) & mask) * xy;
|
||||
|
||||
*dstColor = ((lo >> 8) & mask) | (hi & ~mask);
|
||||
}
|
||||
|
||||
static void test_filter() {
|
||||
for (int r = 0; r <= 0xFF; r++) {
|
||||
SkPMColor c = SkPackARGB32(0xFF, r, r, r);
|
||||
for (int y = 0; y <= 0xF; y++) {
|
||||
for (int x = 0; x <= 0xF; x++) {
|
||||
SkPMColor dst;
|
||||
Filter_32_opaque_portable(x, y, c, c, c, c, &dst);
|
||||
SkASSERT(SkGetPackedA32(dst) == 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkAnimatorView : public SkView {
|
||||
public:
|
||||
SkAnimatorView();
|
||||
|
@ -30,6 +74,7 @@ private:
|
|||
};
|
||||
|
||||
SkAnimatorView::SkAnimatorView() : fAnimator(NULL) {
|
||||
test_filter();
|
||||
}
|
||||
|
||||
SkAnimatorView::~SkAnimatorView() {
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "SkUtils.h"
|
||||
#include "SkImageDecoder.h"
|
||||
|
||||
#include "SkMeshUtils.h"
|
||||
|
||||
static SkPoint SkMakePoint(SkScalar x, SkScalar y) {
|
||||
SkPoint pt;
|
||||
pt.set(x, y);
|
||||
|
@ -21,18 +23,6 @@ static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
|
|||
|
||||
#include "SkBoundaryPatch.h"
|
||||
|
||||
static void set_pts(SkPoint pts[], int R, int C, SkBoundaryPatch* patch) {
|
||||
SkScalar invR = SkScalarInvert(SkIntToScalar(R - 1));
|
||||
SkScalar invC = SkScalarInvert(SkIntToScalar(C - 1));
|
||||
|
||||
for (int y = 0; y < C; y++) {
|
||||
SkScalar yy = y * invC;
|
||||
for (int x = 0; x < R; x++) {
|
||||
*pts++ = patch->evaluate(x * invR, yy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
|
||||
SkScalar x3, SkScalar y3, SkScalar scale = 1) {
|
||||
SkPoint tmp, tmp2;
|
||||
|
@ -53,82 +43,78 @@ static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
|
|||
pts[2] = tmp + tmp2;
|
||||
}
|
||||
|
||||
static void draw_texture(SkCanvas* canvas, const SkPoint verts[], int R, int C,
|
||||
const SkBitmap& texture) {
|
||||
int vertCount = R * C;
|
||||
const int rows = R - 1;
|
||||
const int cols = C - 1;
|
||||
int idxCount = rows * cols * 6;
|
||||
|
||||
SkAutoTArray<SkPoint> texStorage(vertCount);
|
||||
SkPoint* tex = texStorage.get();
|
||||
SkAutoTArray<uint16_t> idxStorage(idxCount);
|
||||
uint16_t* idx = idxStorage.get();
|
||||
|
||||
|
||||
const SkScalar dtx = texture.width() / rows;
|
||||
const SkScalar dty = texture.height() / cols;
|
||||
int index = 0;
|
||||
for (int y = 0; y <= cols; y++) {
|
||||
for (int x = 0; x <= rows; x++) {
|
||||
tex->set(x*dtx, y*dty);
|
||||
tex += 1;
|
||||
|
||||
if (y < cols && x < rows) {
|
||||
*idx++ = index;
|
||||
*idx++ = index + rows + 1;
|
||||
*idx++ = index + 1;
|
||||
|
||||
*idx++ = index + 1;
|
||||
*idx++ = index + rows + 1;
|
||||
*idx++ = index + rows + 2;
|
||||
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
SkPaint paint;
|
||||
paint.setShader(SkShader::CreateBitmapShader(texture,
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kClamp_TileMode))->unref();
|
||||
|
||||
canvas->drawVertices(SkCanvas::kTriangles_VertexMode, vertCount, verts,
|
||||
texStorage.get(), NULL, NULL, idxStorage.get(),
|
||||
idxCount, paint);
|
||||
}
|
||||
|
||||
static void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) {
|
||||
SkCubicBoundaryCurve L, T, R, B;
|
||||
SkCubicBoundary cubic;
|
||||
set_cubic(cubic.fPts + 0, 0, 0, 100, 0, scale);
|
||||
set_cubic(cubic.fPts + 3, 100, 0, 100, 100, scale);
|
||||
set_cubic(cubic.fPts + 6, 100, 100, 0, 100, -scale);
|
||||
set_cubic(cubic.fPts + 9, 0, 100, 0, 0, 0);
|
||||
|
||||
set_cubic(L.fPts, 0, 0, 0, 100, scale);
|
||||
set_cubic(T.fPts, 0, 0, 100, 0, scale);
|
||||
set_cubic(R.fPts, 100, 0, 100, 100, -scale);
|
||||
set_cubic(B.fPts, 0, 100, 100, 100, 0);
|
||||
|
||||
SkBoundaryPatch patch;
|
||||
patch.setCurve(SkBoundaryPatch::kLeft, &L);
|
||||
patch.setCurve(SkBoundaryPatch::kTop, &T);
|
||||
patch.setCurve(SkBoundaryPatch::kRight, &R);
|
||||
patch.setCurve(SkBoundaryPatch::kBottom, &B);
|
||||
|
||||
const int Rows = 25;
|
||||
const int Cols = 25;
|
||||
patch.setBoundary(&cubic);
|
||||
|
||||
const int Rows = 16;
|
||||
const int Cols = 16;
|
||||
SkPoint pts[Rows * Cols];
|
||||
set_pts(pts, Rows, Cols, &patch);
|
||||
patch.evalPatch(pts, Rows, Cols);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterBitmap(true);
|
||||
paint.setStrokeWidth(1);
|
||||
paint.setStrokeCap(SkPaint::kRound_Cap);
|
||||
|
||||
|
||||
canvas->translate(50, 50);
|
||||
canvas->scale(3, 3);
|
||||
|
||||
SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
|
||||
}
|
||||
|
||||
draw_texture(canvas, pts, Rows, Cols, bm);
|
||||
// canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(pts),
|
||||
// pts, paint);
|
||||
static void test_drag(SkCanvas* canvas, const SkBitmap& bm,
|
||||
const SkPoint& p0, const SkPoint& p1) {
|
||||
SkCubicBoundary cubic;
|
||||
set_cubic(cubic.fPts + 0, 0, 0, 100, 0, 0);
|
||||
set_cubic(cubic.fPts + 3, 100, 0, 100, 100, 0);
|
||||
set_cubic(cubic.fPts + 6, 100, 100, 0, 100, 0);
|
||||
set_cubic(cubic.fPts + 9, 0, 100, 0, 0, 0);
|
||||
|
||||
#if 0
|
||||
cubic.fPts[1] += p1 - p0;
|
||||
cubic.fPts[2] += p1 - p0;
|
||||
#else
|
||||
SkScalar dx = p1.fX - p0.fX;
|
||||
if (dx > 0) dx = 0;
|
||||
SkScalar dy = p1.fY - p0.fY;
|
||||
if (dy > 0) dy = 0;
|
||||
|
||||
cubic.fPts[1].fY += dy;
|
||||
cubic.fPts[2].fY += dy;
|
||||
cubic.fPts[10].fX += dx;
|
||||
cubic.fPts[11].fX += dx;
|
||||
#endif
|
||||
|
||||
SkBoundaryPatch patch;
|
||||
patch.setBoundary(&cubic);
|
||||
|
||||
const int Rows = 16;
|
||||
const int Cols = 16;
|
||||
SkPoint pts[Rows * Cols];
|
||||
patch.evalPatch(pts, Rows, Cols);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterBitmap(true);
|
||||
paint.setStrokeWidth(1);
|
||||
paint.setStrokeCap(SkPaint::kRound_Cap);
|
||||
|
||||
canvas->translate(50, 50);
|
||||
canvas->scale(3, 3);
|
||||
|
||||
SkAutoCanvasRestore acr(canvas, true);
|
||||
|
||||
SkRect r = { 0, 0, 100, 100 };
|
||||
canvas->clipRect(r);
|
||||
SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -255,7 +241,7 @@ void Mesh::drawWireframe(SkCanvas* canvas, const SkPaint& paint) {
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkScalar gScale = 0;
|
||||
static SkScalar gDScale = 0.01;
|
||||
static SkScalar gDScale = 0.02;
|
||||
|
||||
class WarpView : public SkView {
|
||||
Mesh fMesh, fOrig;
|
||||
|
@ -263,8 +249,8 @@ class WarpView : public SkView {
|
|||
public:
|
||||
WarpView() {
|
||||
SkBitmap bm;
|
||||
// SkImageDecoder::DecodeFile("/skimages/beach.jpg", &bm);
|
||||
SkImageDecoder::DecodeFile("/beach_shot.JPG", &bm);
|
||||
SkImageDecoder::DecodeFile("/skimages/beach.jpg", &bm);
|
||||
// SkImageDecoder::DecodeFile("/beach_shot.JPG", &bm);
|
||||
fBitmap = bm;
|
||||
|
||||
SkRect bounds, texture;
|
||||
|
@ -275,6 +261,9 @@ public:
|
|||
// fMesh.init(bounds, fBitmap.width() / 40, fBitmap.height() / 40, texture);
|
||||
fMesh.init(bounds, 30, 30, texture);
|
||||
fOrig = fMesh;
|
||||
|
||||
fP0.set(0, 0);
|
||||
fP1 = fP0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -287,56 +276,9 @@ protected:
|
|||
return this->INHERITED::onQuery(evt);
|
||||
}
|
||||
|
||||
static SkPoint make_pt(SkScalar x, SkScalar y) {
|
||||
SkPoint pt;
|
||||
pt.set(x, y);
|
||||
return pt;
|
||||
}
|
||||
|
||||
static SkScalar mapx0(SkScalar min, SkScalar max, SkScalar x0, SkScalar x1,
|
||||
SkScalar x) {
|
||||
if (x < x0) {
|
||||
SkASSERT(x0 > min);
|
||||
return x1 - SkScalarMulDiv(x1 - min, x0 - x, x0 - min);
|
||||
} else {
|
||||
SkASSERT(max > x0);
|
||||
return x1 + SkScalarMulDiv(max - x1, x - x0, max - x0);
|
||||
}
|
||||
}
|
||||
|
||||
static SkScalar mapx1(SkScalar min, SkScalar max, SkScalar x0, SkScalar x1,
|
||||
SkScalar x) {
|
||||
SkScalar newx;
|
||||
if (x < x0) {
|
||||
SkASSERT(x0 > min);
|
||||
newx = x1 - SkScalarMulDiv(x1 - min, x0 - x, x0 - min);
|
||||
} else {
|
||||
SkASSERT(max > x0);
|
||||
newx = x1 + SkScalarMulDiv(max - x1, x - x0, max - x0);
|
||||
}
|
||||
return x + (newx - x) * 0.5f;
|
||||
}
|
||||
|
||||
static SkPoint mappt(const SkRect& r, const SkPoint& p0, const SkPoint& p1,
|
||||
const SkPoint& pt) {
|
||||
return make_pt(mapx0(r.fLeft, r.fRight, p0.fX, p1.fX, pt.fX),
|
||||
mapx0(r.fTop, r.fBottom, p0.fY, p1.fY, pt.fY));
|
||||
}
|
||||
|
||||
void warp(const SkPoint& p0, const SkPoint& p1) {
|
||||
const SkRect& bounds = fOrig.bounds();
|
||||
int rows = fMesh.rows();
|
||||
int cols = fMesh.cols();
|
||||
|
||||
SkRect r = bounds;
|
||||
r.inset(bounds.width() / 256, bounds.height() / 256);
|
||||
if (r.contains(p0)) {
|
||||
for (int y = 1; y < cols; y++) {
|
||||
for (int x = 1; x < rows; x++) {
|
||||
fMesh.pt(x, y) = mappt(bounds, p0, p1, fOrig.pt(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
fP0 = p0;
|
||||
fP1 = p1;
|
||||
}
|
||||
|
||||
virtual void onDraw(SkCanvas* canvas) {
|
||||
|
@ -352,7 +294,8 @@ protected:
|
|||
paint.setShader(NULL);
|
||||
paint.setColor(SK_ColorRED);
|
||||
// fMesh.draw(canvas, paint);
|
||||
|
||||
|
||||
#if 0
|
||||
test_patch(canvas, fBitmap, gScale);
|
||||
gScale += gDScale;
|
||||
if (gScale > 2) {
|
||||
|
@ -361,6 +304,9 @@ protected:
|
|||
gDScale = -gDScale;
|
||||
}
|
||||
this->inval(NULL);
|
||||
#else
|
||||
test_drag(canvas, fBitmap, fP0, fP1);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
|
||||
|
@ -375,7 +321,7 @@ protected:
|
|||
|
||||
private:
|
||||
SkIRect fBase, fRect;
|
||||
|
||||
SkPoint fP0, fP1;
|
||||
typedef SkView INHERITED;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
#include "SkMeshUtils.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkPaint.h"
|
||||
|
||||
SkMeshIndices::SkMeshIndices() {
|
||||
sk_bzero(this, sizeof(*this));
|
||||
}
|
||||
|
||||
SkMeshIndices::~SkMeshIndices() {
|
||||
sk_free(fStorage);
|
||||
}
|
||||
|
||||
bool SkMeshIndices::init(SkPoint tex[], uint16_t indices[],
|
||||
int texW, int texH, int rows, int cols) {
|
||||
if (rows < 2 || cols < 2) {
|
||||
sk_free(fStorage);
|
||||
fStorage = NULL;
|
||||
fTex = NULL;
|
||||
fIndices = NULL;
|
||||
fTexCount = fIndexCount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
sk_free(fStorage);
|
||||
fStorage = NULL;
|
||||
|
||||
fTexCount = rows * cols;
|
||||
rows -= 1;
|
||||
cols -= 1;
|
||||
fIndexCount = rows * cols * 6;
|
||||
|
||||
if (tex) {
|
||||
fTex = tex;
|
||||
fIndices = indices;
|
||||
} else {
|
||||
fStorage = sk_malloc_throw(fTexCount * sizeof(SkPoint) +
|
||||
fIndexCount * sizeof(uint16_t));
|
||||
fTex = (SkPoint*)fStorage;
|
||||
fIndices = (uint16_t*)(fTex + fTexCount);
|
||||
}
|
||||
|
||||
// compute the indices
|
||||
{
|
||||
uint16_t* idx = fIndices;
|
||||
int index = 0;
|
||||
for (int y = 0; y < cols; y++) {
|
||||
for (int x = 0; x < rows; x++) {
|
||||
*idx++ = index;
|
||||
*idx++ = index + rows + 1;
|
||||
*idx++ = index + 1;
|
||||
|
||||
*idx++ = index + 1;
|
||||
*idx++ = index + rows + 1;
|
||||
*idx++ = index + rows + 2;
|
||||
|
||||
index += 1;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// compute texture coordinates
|
||||
{
|
||||
SkPoint* tex = fTex;
|
||||
const SkScalar dx = SkIntToScalar(texW) / rows;
|
||||
const SkScalar dy = SkIntToScalar(texH) / cols;
|
||||
for (int y = 0; y <= cols; y++) {
|
||||
for (int x = 0; x <= rows; x++) {
|
||||
tex->set(x*dx, y*dy);
|
||||
tex += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
void SkMeshUtils::Draw(SkCanvas* canvas, const SkBitmap& bitmap,
|
||||
int rows, int cols, const SkPoint verts[],
|
||||
const SkColor colors[], const SkPaint& paint) {
|
||||
SkMeshIndices idx;
|
||||
|
||||
if (idx.init(bitmap.width(), bitmap.height(), rows, cols)) {
|
||||
SkPaint p(paint);
|
||||
p.setShader(SkShader::CreateBitmapShader(bitmap,
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kClamp_TileMode))->unref();
|
||||
canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
|
||||
rows * cols, verts, idx.tex(), colors, NULL,
|
||||
idx.indices(), idx.indexCount(), p);
|
||||
}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче