| Index: samplecode/SampleWarp.cpp
|
| diff --git a/samplecode/SampleWarp.cpp b/samplecode/SampleWarp.cpp
|
| deleted file mode 100644
|
| index e9455a6c3952c95ee02e3383d23daabe964d096b..0000000000000000000000000000000000000000
|
| --- a/samplecode/SampleWarp.cpp
|
| +++ /dev/null
|
| @@ -1,473 +0,0 @@
|
| -
|
| -/*
|
| - * Copyright 2011 Google Inc.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -#include "SampleCode.h"
|
| -#include "SkView.h"
|
| -#include "SkCanvas.h"
|
| -#include "SkGradientShader.h"
|
| -#include "SkPath.h"
|
| -#include "SkRegion.h"
|
| -#include "SkShader.h"
|
| -#include "SkUtils.h"
|
| -#include "SkImageDecoder.h"
|
| -
|
| -#include "SkBlurMaskFilter.h"
|
| -#include "SkTableMaskFilter.h"
|
| -
|
| -#define kNearlyZero (SK_Scalar1 / 8092)
|
| -
|
| -static void test_bigblur(SkCanvas* canvas) {
|
| - canvas->drawColor(SK_ColorBLACK);
|
| -
|
| - SkBitmap orig, mask;
|
| - SkImageDecoder::DecodeFile("/skimages/app_icon.png", &orig);
|
| -
|
| - SkMaskFilter* mf = SkBlurMaskFilter::Create(8, SkBlurMaskFilter::kNormal_BlurStyle);
|
| - SkPaint paint;
|
| - paint.setMaskFilter(mf)->unref();
|
| - SkIPoint offset;
|
| - orig.extractAlpha(&mask, &paint, &offset);
|
| -
|
| - paint.setColor(0xFFBB8800);
|
| - paint.setColor(SK_ColorWHITE);
|
| -
|
| - int i;
|
| - canvas->save();
|
| - float gamma = 0.8;
|
| - for (i = 0; i < 5; i++) {
|
| - paint.setMaskFilter(SkTableMaskFilter::CreateGamma(gamma))->unref();
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - paint.setMaskFilter(NULL);
|
| - canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
|
| - gamma -= 0.1;
|
| - canvas->translate(120, 0);
|
| - }
|
| - canvas->restore();
|
| - canvas->translate(0, 160);
|
| -
|
| - for (i = 0; i < 5; i++) {
|
| - paint.setMaskFilter(SkTableMaskFilter::CreateClip(i*30, 255 - 20))->unref();
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - paint.setMaskFilter(NULL);
|
| - canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
|
| - canvas->translate(120, 0);
|
| - }
|
| -
|
| -#if 0
|
| - paint.setColor(0xFFFFFFFF);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - paint.setMaskFilter(NULL);
|
| - canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
|
| -
|
| - canvas->translate(120, 0);
|
| -
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
|
| -
|
| - canvas->translate(120, 0);
|
| -
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
|
| -
|
| - canvas->translate(120, 0);
|
| -
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
|
| -
|
| - canvas->translate(120, 0);
|
| -
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(mask, 0, 0, &paint);
|
| - canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
|
| -#endif
|
| -}
|
| -
|
| -#include "SkMeshUtils.h"
|
| -
|
| -static SkPoint SkMakePoint(SkScalar x, SkScalar y) {
|
| - SkPoint pt;
|
| - pt.set(x, y);
|
| - return pt;
|
| -}
|
| -
|
| -static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
|
| - return SkMakePoint(SkScalarInterp(a.fX, b.fX, t),
|
| - SkScalarInterp(a.fY, b.fY, t));
|
| -}
|
| -
|
| -#include "SkBoundaryPatch.h"
|
| -
|
| -static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
|
| - SkScalar x3, SkScalar y3, SkScalar scale = 1) {
|
| - SkPoint tmp, tmp2;
|
| -
|
| - pts[0].set(x0, y0);
|
| - pts[3].set(x3, y3);
|
| -
|
| - tmp = SkPointInterp(pts[0], pts[3], SK_Scalar1/3);
|
| - tmp2 = pts[0] - tmp;
|
| - tmp2.rotateCW();
|
| - tmp2.scale(scale);
|
| - pts[1] = tmp + tmp2;
|
| -
|
| - tmp = SkPointInterp(pts[0], pts[3], 2*SK_Scalar1/3);
|
| - tmp2 = pts[3] - tmp;
|
| - tmp2.rotateCW();
|
| - tmp2.scale(scale);
|
| - pts[2] = tmp + tmp2;
|
| -}
|
| -
|
| -static void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) {
|
| - 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);
|
| -
|
| - 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);
|
| -
|
| - SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, 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);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -class Mesh {
|
| -public:
|
| - Mesh();
|
| - ~Mesh();
|
| -
|
| - Mesh& operator=(const Mesh& src);
|
| -
|
| - void init(const SkRect& bounds, int rows, int cols,
|
| - const SkRect& texture);
|
| -
|
| - const SkRect& bounds() const { return fBounds; }
|
| -
|
| - int rows() const { return fRows; }
|
| - int cols() const { return fCols; }
|
| - SkPoint& pt(int row, int col) {
|
| - return fPts[row * (fRows + 1) + col];
|
| - }
|
| -
|
| - void draw(SkCanvas*, const SkPaint&);
|
| - void drawWireframe(SkCanvas* canvas, const SkPaint& paint);
|
| -
|
| -private:
|
| - SkRect fBounds;
|
| - int fRows, fCols;
|
| - SkPoint* fPts;
|
| - SkPoint* fTex; // just points into fPts, not separately allocated
|
| - int fCount;
|
| - uint16_t* fIndices;
|
| - int fIndexCount;
|
| -};
|
| -
|
| -Mesh::Mesh() : fPts(NULL), fCount(0), fIndices(NULL), fIndexCount(0) {}
|
| -
|
| -Mesh::~Mesh() {
|
| - delete[] fPts;
|
| - delete[] fIndices;
|
| -}
|
| -
|
| -Mesh& Mesh::operator=(const Mesh& src) {
|
| - delete[] fPts;
|
| - delete[] fIndices;
|
| -
|
| - fBounds = src.fBounds;
|
| - fRows = src.fRows;
|
| - fCols = src.fCols;
|
| -
|
| - fCount = src.fCount;
|
| - fPts = new SkPoint[fCount * 2];
|
| - fTex = fPts + fCount;
|
| - memcpy(fPts, src.fPts, fCount * 2 * sizeof(SkPoint));
|
| -
|
| - delete[] fIndices;
|
| - fIndexCount = src.fIndexCount;
|
| - fIndices = new uint16_t[fIndexCount];
|
| - memcpy(fIndices, src.fIndices, fIndexCount * sizeof(uint16_t));
|
| -
|
| - return *this;
|
| -}
|
| -
|
| -void Mesh::init(const SkRect& bounds, int rows, int cols,
|
| - const SkRect& texture) {
|
| - SkASSERT(rows > 0 && cols > 0);
|
| -
|
| - fBounds = bounds;
|
| - fRows = rows;
|
| - fCols = cols;
|
| -
|
| - delete[] fPts;
|
| - fCount = (rows + 1) * (cols + 1);
|
| - fPts = new SkPoint[fCount * 2];
|
| - fTex = fPts + fCount;
|
| -
|
| - delete[] fIndices;
|
| - fIndexCount = rows * cols * 6;
|
| - fIndices = new uint16_t[fIndexCount];
|
| -
|
| - SkPoint* pts = fPts;
|
| - const SkScalar dx = bounds.width() / rows;
|
| - const SkScalar dy = bounds.height() / cols;
|
| - SkPoint* tex = fTex;
|
| - const SkScalar dtx = texture.width() / rows;
|
| - const SkScalar dty = texture.height() / cols;
|
| - uint16_t* idx = fIndices;
|
| - int index = 0;
|
| - for (int y = 0; y <= cols; y++) {
|
| - for (int x = 0; x <= rows; x++) {
|
| - pts->set(bounds.fLeft + x*dx, bounds.fTop + y*dy);
|
| - pts += 1;
|
| - tex->set(texture.fLeft + x*dtx, texture.fTop + 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;
|
| - }
|
| -}
|
| -
|
| -void Mesh::draw(SkCanvas* canvas, const SkPaint& paint) {
|
| - canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
|
| - fPts, fTex, NULL, NULL, fIndices, fIndexCount,
|
| - paint);
|
| -}
|
| -
|
| -void Mesh::drawWireframe(SkCanvas* canvas, const SkPaint& paint) {
|
| - canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
|
| - fPts, NULL, NULL, NULL, fIndices, fIndexCount,
|
| - paint);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -class WarpView : public SkView {
|
| - Mesh fMesh, fOrig;
|
| - SkBitmap fBitmap;
|
| - SkMatrix fMatrix, fInverse;
|
| -public:
|
| - WarpView() {
|
| - SkBitmap bm;
|
| -// SkImageDecoder::DecodeFile("/skimages/marker.png", &bm);
|
| - SkImageDecoder::DecodeFile("/skimages/logo.gif", &bm);
|
| - // SkImageDecoder::DecodeFile("/beach_shot.JPG", &bm);
|
| - fBitmap = bm;
|
| -
|
| - SkRect bounds, texture;
|
| - texture.set(0, 0, SkIntToScalar(fBitmap.width()),
|
| - SkIntToScalar(fBitmap.height()));
|
| - bounds = texture;
|
| -
|
| -// fMesh.init(bounds, fBitmap.width() / 40, fBitmap.height() / 40, texture);
|
| - fMesh.init(bounds, fBitmap.width()/16, fBitmap.height()/16, texture);
|
| - fOrig = fMesh;
|
| -
|
| - fP0.set(0, 0);
|
| - fP1 = fP0;
|
| -
|
| - fMatrix.setScale(2, 2);
|
| - fMatrix.invert(&fInverse);
|
| - }
|
| -
|
| -protected:
|
| - // overrides from SkEventSink
|
| - virtual bool onQuery(SkEvent* evt) {
|
| - if (SampleCode::TitleQ(*evt)) {
|
| - SampleCode::TitleR(evt, "Warp");
|
| - return true;
|
| - }
|
| - return this->INHERITED::onQuery(evt);
|
| - }
|
| -
|
| - static SkPoint apply_warp(const SkVector& drag, SkScalar dragLength,
|
| - const SkPoint& dragStart, const SkPoint& dragCurr,
|
| - const SkPoint& orig) {
|
| - SkVector delta = orig - dragCurr;
|
| - SkScalar length = SkPoint::Normalize(&delta);
|
| - if (length <= kNearlyZero) {
|
| - return orig;
|
| - }
|
| -
|
| - const SkScalar period = 20;
|
| - const SkScalar mag = dragLength / 3;
|
| -
|
| - SkScalar d = length / (period);
|
| - d = mag * SkScalarSin(d) / d;
|
| - SkScalar dx = delta.fX * d;
|
| - SkScalar dy = delta.fY * d;
|
| - SkScalar px = orig.fX + dx;
|
| - SkScalar py = orig.fY + dy;
|
| - return SkPoint::Make(px, py);
|
| - }
|
| -
|
| - static SkPoint apply_warp2(const SkVector& drag, SkScalar dragLength,
|
| - const SkPoint& dragStart, const SkPoint& dragCurr,
|
| - const SkPoint& orig) {
|
| - SkVector delta = orig - dragCurr;
|
| - SkScalar length = SkPoint::Normalize(&delta);
|
| - if (length <= kNearlyZero) {
|
| - return orig;
|
| - }
|
| -
|
| - const SkScalar period = 10 + dragLength/4;
|
| - const SkScalar mag = dragLength / 3;
|
| -
|
| - SkScalar d = length / (period);
|
| - if (d > SK_ScalarPI) {
|
| - d = SK_ScalarPI;
|
| - }
|
| -
|
| - d = -mag * SkScalarSin(d);
|
| -
|
| - SkScalar dx = delta.fX * d;
|
| - SkScalar dy = delta.fY * d;
|
| - SkScalar px = orig.fX + dx;
|
| - SkScalar py = orig.fY + dy;
|
| - return SkPoint::Make(px, py);
|
| - }
|
| -
|
| - typedef SkPoint (*WarpProc)(const SkVector& drag, SkScalar dragLength,
|
| - const SkPoint& dragStart, const SkPoint& dragCurr,
|
| - const SkPoint& orig);
|
| -
|
| - void warp(const SkPoint& p0, const SkPoint& p1) {
|
| - WarpProc proc = apply_warp2;
|
| - SkPoint delta = p1 - p0;
|
| - SkScalar length = SkPoint::Normalize(&delta);
|
| - for (int y = 0; y < fMesh.rows(); y++) {
|
| - for (int x = 0; x < fMesh.cols(); x++) {
|
| - fMesh.pt(x, y) = proc(delta, length, p0, p1, fOrig.pt(x, y));
|
| - }
|
| - }
|
| - fP0 = p0;
|
| - fP1 = p1;
|
| - }
|
| -
|
| - virtual void onDraw(SkCanvas* canvas) {
|
| - canvas->drawColor(SK_ColorLTGRAY);
|
| - // test_bigblur(canvas); return;
|
| -
|
| - canvas->concat(fMatrix);
|
| -
|
| - SkPaint paint;
|
| - paint.setFilterBitmap(true);
|
| - paint.setShader(SkShader::CreateBitmapShader(fBitmap,
|
| - SkShader::kClamp_TileMode,
|
| - SkShader::kClamp_TileMode))->unref();
|
| - fMesh.draw(canvas, paint); //return;
|
| -
|
| - paint.setShader(NULL);
|
| - paint.setColor(SK_ColorRED);
|
| - fMesh.draw(canvas, paint);
|
| -
|
| - // test_drag(canvas, fBitmap, fP0, fP1);
|
| - }
|
| -
|
| - virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
|
| - return new Click(this);
|
| - }
|
| -
|
| - virtual bool onClick(Click* click) {
|
| - SkPoint pts[2] = { click->fOrig, click->fCurr };
|
| - fInverse.mapPoints(pts, 2);
|
| - this->warp(pts[0], pts[1]);
|
| - this->inval(NULL);
|
| - return true;
|
| - }
|
| -
|
| -private:
|
| - SkIRect fBase, fRect;
|
| - SkPoint fP0, fP1;
|
| - typedef SkView INHERITED;
|
| -};
|
| -
|
| -//////////////////////////////////////////////////////////////////////////////
|
| -
|
| -static SkView* MyFactory() { return new WarpView; }
|
| -static SkViewRegister reg(MyFactory);
|
|
|