diff options
author | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-10-28 14:25:34 +0000 |
---|---|---|
committer | reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-10-28 14:25:34 +0000 |
commit | 2ee7c640150a863f2859eb0aaf4dfe7ad7836f34 (patch) | |
tree | 14932aa2f166fecb6f36b2fa4b31ad96eac0b288 /samplecode | |
parent | b577b41c8ec26c21ae599e80a2707d42f03eaa60 (diff) |
update on boundary patches
git-svn-id: http://skia.googlecode.com/svn/trunk@409 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'samplecode')
-rw-r--r-- | samplecode/SampleAnimator.cpp | 45 | ||||
-rw-r--r-- | samplecode/SampleWarp.cpp | 200 |
2 files changed, 118 insertions, 127 deletions
diff --git a/samplecode/SampleAnimator.cpp b/samplecode/SampleAnimator.cpp index 2909ebc781..4ba88729a8 100644 --- a/samplecode/SampleAnimator.cpp +++ b/samplecode/SampleAnimator.cpp @@ -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() { diff --git a/samplecode/SampleWarp.cpp b/samplecode/SampleWarp.cpp index c7adad9490..16c0bc82be 100644 --- a/samplecode/SampleWarp.cpp +++ b/samplecode/SampleWarp.cpp @@ -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; - } - +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.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); + 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_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) { - SkCubicBoundaryCurve L, T, R, B; +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); - 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); +#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.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); + + SkAutoCanvasRestore acr(canvas, true); - draw_texture(canvas, pts, Rows, Cols, bm); -// canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(pts), -// pts, paint); + 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; }; |