Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(645)

Side by Side Diff: samplecode/SampleWarp.cpp

Issue 901933004: migrate more samples over to SkAnimTImer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix warning Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « samplecode/SampleRotateCircles.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 /*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8 #include "SampleCode.h"
9 #include "SkView.h"
10 #include "SkCanvas.h"
11 #include "SkGradientShader.h"
12 #include "SkPath.h"
13 #include "SkRegion.h"
14 #include "SkShader.h"
15 #include "SkUtils.h"
16 #include "SkImageDecoder.h"
17
18 #include "SkBlurMaskFilter.h"
19 #include "SkTableMaskFilter.h"
20
21 #define kNearlyZero (SK_Scalar1 / 8092)
22
23 static void test_bigblur(SkCanvas* canvas) {
24 canvas->drawColor(SK_ColorBLACK);
25
26 SkBitmap orig, mask;
27 SkImageDecoder::DecodeFile("/skimages/app_icon.png", &orig);
28
29 SkMaskFilter* mf = SkBlurMaskFilter::Create(8, SkBlurMaskFilter::kNormal_Blu rStyle);
30 SkPaint paint;
31 paint.setMaskFilter(mf)->unref();
32 SkIPoint offset;
33 orig.extractAlpha(&mask, &paint, &offset);
34
35 paint.setColor(0xFFBB8800);
36 paint.setColor(SK_ColorWHITE);
37
38 int i;
39 canvas->save();
40 float gamma = 0.8;
41 for (i = 0; i < 5; i++) {
42 paint.setMaskFilter(SkTableMaskFilter::CreateGamma(gamma))->unref();
43 canvas->drawBitmap(mask, 0, 0, &paint);
44 paint.setMaskFilter(NULL);
45 canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
46 gamma -= 0.1;
47 canvas->translate(120, 0);
48 }
49 canvas->restore();
50 canvas->translate(0, 160);
51
52 for (i = 0; i < 5; i++) {
53 paint.setMaskFilter(SkTableMaskFilter::CreateClip(i*30, 255 - 20))->unre f();
54 canvas->drawBitmap(mask, 0, 0, &paint);
55 paint.setMaskFilter(NULL);
56 canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
57 canvas->translate(120, 0);
58 }
59
60 #if 0
61 paint.setColor(0xFFFFFFFF);
62 canvas->drawBitmap(mask, 0, 0, &paint);
63 paint.setMaskFilter(NULL);
64 canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
65
66 canvas->translate(120, 0);
67
68 canvas->drawBitmap(mask, 0, 0, &paint);
69 canvas->drawBitmap(mask, 0, 0, &paint);
70 canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
71
72 canvas->translate(120, 0);
73
74 canvas->drawBitmap(mask, 0, 0, &paint);
75 canvas->drawBitmap(mask, 0, 0, &paint);
76 canvas->drawBitmap(mask, 0, 0, &paint);
77 canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
78
79 canvas->translate(120, 0);
80
81 canvas->drawBitmap(mask, 0, 0, &paint);
82 canvas->drawBitmap(mask, 0, 0, &paint);
83 canvas->drawBitmap(mask, 0, 0, &paint);
84 canvas->drawBitmap(mask, 0, 0, &paint);
85 canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
86
87 canvas->translate(120, 0);
88
89 canvas->drawBitmap(mask, 0, 0, &paint);
90 canvas->drawBitmap(mask, 0, 0, &paint);
91 canvas->drawBitmap(mask, 0, 0, &paint);
92 canvas->drawBitmap(mask, 0, 0, &paint);
93 canvas->drawBitmap(mask, 0, 0, &paint);
94 canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint);
95 #endif
96 }
97
98 #include "SkMeshUtils.h"
99
100 static SkPoint SkMakePoint(SkScalar x, SkScalar y) {
101 SkPoint pt;
102 pt.set(x, y);
103 return pt;
104 }
105
106 static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
107 return SkMakePoint(SkScalarInterp(a.fX, b.fX, t),
108 SkScalarInterp(a.fY, b.fY, t));
109 }
110
111 #include "SkBoundaryPatch.h"
112
113 static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
114 SkScalar x3, SkScalar y3, SkScalar scale = 1) {
115 SkPoint tmp, tmp2;
116
117 pts[0].set(x0, y0);
118 pts[3].set(x3, y3);
119
120 tmp = SkPointInterp(pts[0], pts[3], SK_Scalar1/3);
121 tmp2 = pts[0] - tmp;
122 tmp2.rotateCW();
123 tmp2.scale(scale);
124 pts[1] = tmp + tmp2;
125
126 tmp = SkPointInterp(pts[0], pts[3], 2*SK_Scalar1/3);
127 tmp2 = pts[3] - tmp;
128 tmp2.rotateCW();
129 tmp2.scale(scale);
130 pts[2] = tmp + tmp2;
131 }
132
133 static void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) {
134 SkCubicBoundary cubic;
135 set_cubic(cubic.fPts + 0, 0, 0, 100, 0, scale);
136 set_cubic(cubic.fPts + 3, 100, 0, 100, 100, scale);
137 set_cubic(cubic.fPts + 6, 100, 100, 0, 100, -scale);
138 set_cubic(cubic.fPts + 9, 0, 100, 0, 0, 0);
139
140 SkBoundaryPatch patch;
141 patch.setBoundary(&cubic);
142
143 const int Rows = 16;
144 const int Cols = 16;
145 SkPoint pts[Rows * Cols];
146 patch.evalPatch(pts, Rows, Cols);
147
148 SkPaint paint;
149 paint.setAntiAlias(true);
150 paint.setFilterBitmap(true);
151 paint.setStrokeWidth(1);
152 paint.setStrokeCap(SkPaint::kRound_Cap);
153
154 canvas->translate(50, 50);
155 canvas->scale(3, 3);
156
157 SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
158 }
159
160 static void test_drag(SkCanvas* canvas, const SkBitmap& bm,
161 const SkPoint& p0, const SkPoint& p1) {
162 SkCubicBoundary cubic;
163 set_cubic(cubic.fPts + 0, 0, 0, 100, 0, 0);
164 set_cubic(cubic.fPts + 3, 100, 0, 100, 100, 0);
165 set_cubic(cubic.fPts + 6, 100, 100, 0, 100, 0);
166 set_cubic(cubic.fPts + 9, 0, 100, 0, 0, 0);
167
168 #if 0
169 cubic.fPts[1] += p1 - p0;
170 cubic.fPts[2] += p1 - p0;
171 #else
172 SkScalar dx = p1.fX - p0.fX;
173 if (dx > 0) dx = 0;
174 SkScalar dy = p1.fY - p0.fY;
175 if (dy > 0) dy = 0;
176
177 cubic.fPts[1].fY += dy;
178 cubic.fPts[2].fY += dy;
179 cubic.fPts[10].fX += dx;
180 cubic.fPts[11].fX += dx;
181 #endif
182
183 SkBoundaryPatch patch;
184 patch.setBoundary(&cubic);
185
186 const int Rows = 16;
187 const int Cols = 16;
188 SkPoint pts[Rows * Cols];
189 patch.evalPatch(pts, Rows, Cols);
190
191 SkPaint paint;
192 paint.setAntiAlias(true);
193 paint.setFilterBitmap(true);
194 paint.setStrokeWidth(1);
195 paint.setStrokeCap(SkPaint::kRound_Cap);
196
197 canvas->translate(50, 50);
198 canvas->scale(3, 3);
199
200 SkAutoCanvasRestore acr(canvas, true);
201
202 SkRect r = { 0, 0, 100, 100 };
203 canvas->clipRect(r);
204 SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
205 }
206
207 ///////////////////////////////////////////////////////////////////////////////
208
209 class Mesh {
210 public:
211 Mesh();
212 ~Mesh();
213
214 Mesh& operator=(const Mesh& src);
215
216 void init(const SkRect& bounds, int rows, int cols,
217 const SkRect& texture);
218
219 const SkRect& bounds() const { return fBounds; }
220
221 int rows() const { return fRows; }
222 int cols() const { return fCols; }
223 SkPoint& pt(int row, int col) {
224 return fPts[row * (fRows + 1) + col];
225 }
226
227 void draw(SkCanvas*, const SkPaint&);
228 void drawWireframe(SkCanvas* canvas, const SkPaint& paint);
229
230 private:
231 SkRect fBounds;
232 int fRows, fCols;
233 SkPoint* fPts;
234 SkPoint* fTex; // just points into fPts, not separately allocated
235 int fCount;
236 uint16_t* fIndices;
237 int fIndexCount;
238 };
239
240 Mesh::Mesh() : fPts(NULL), fCount(0), fIndices(NULL), fIndexCount(0) {}
241
242 Mesh::~Mesh() {
243 delete[] fPts;
244 delete[] fIndices;
245 }
246
247 Mesh& Mesh::operator=(const Mesh& src) {
248 delete[] fPts;
249 delete[] fIndices;
250
251 fBounds = src.fBounds;
252 fRows = src.fRows;
253 fCols = src.fCols;
254
255 fCount = src.fCount;
256 fPts = new SkPoint[fCount * 2];
257 fTex = fPts + fCount;
258 memcpy(fPts, src.fPts, fCount * 2 * sizeof(SkPoint));
259
260 delete[] fIndices;
261 fIndexCount = src.fIndexCount;
262 fIndices = new uint16_t[fIndexCount];
263 memcpy(fIndices, src.fIndices, fIndexCount * sizeof(uint16_t));
264
265 return *this;
266 }
267
268 void Mesh::init(const SkRect& bounds, int rows, int cols,
269 const SkRect& texture) {
270 SkASSERT(rows > 0 && cols > 0);
271
272 fBounds = bounds;
273 fRows = rows;
274 fCols = cols;
275
276 delete[] fPts;
277 fCount = (rows + 1) * (cols + 1);
278 fPts = new SkPoint[fCount * 2];
279 fTex = fPts + fCount;
280
281 delete[] fIndices;
282 fIndexCount = rows * cols * 6;
283 fIndices = new uint16_t[fIndexCount];
284
285 SkPoint* pts = fPts;
286 const SkScalar dx = bounds.width() / rows;
287 const SkScalar dy = bounds.height() / cols;
288 SkPoint* tex = fTex;
289 const SkScalar dtx = texture.width() / rows;
290 const SkScalar dty = texture.height() / cols;
291 uint16_t* idx = fIndices;
292 int index = 0;
293 for (int y = 0; y <= cols; y++) {
294 for (int x = 0; x <= rows; x++) {
295 pts->set(bounds.fLeft + x*dx, bounds.fTop + y*dy);
296 pts += 1;
297 tex->set(texture.fLeft + x*dtx, texture.fTop + y*dty);
298 tex += 1;
299
300 if (y < cols && x < rows) {
301 *idx++ = index;
302 *idx++ = index + rows + 1;
303 *idx++ = index + 1;
304
305 *idx++ = index + 1;
306 *idx++ = index + rows + 1;
307 *idx++ = index + rows + 2;
308
309 index += 1;
310 }
311 }
312 index += 1;
313 }
314 }
315
316 void Mesh::draw(SkCanvas* canvas, const SkPaint& paint) {
317 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
318 fPts, fTex, NULL, NULL, fIndices, fIndexCount,
319 paint);
320 }
321
322 void Mesh::drawWireframe(SkCanvas* canvas, const SkPaint& paint) {
323 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
324 fPts, NULL, NULL, NULL, fIndices, fIndexCount,
325 paint);
326 }
327
328 ///////////////////////////////////////////////////////////////////////////////
329
330 class WarpView : public SkView {
331 Mesh fMesh, fOrig;
332 SkBitmap fBitmap;
333 SkMatrix fMatrix, fInverse;
334 public:
335 WarpView() {
336 SkBitmap bm;
337 // SkImageDecoder::DecodeFile("/skimages/marker.png", &bm);
338 SkImageDecoder::DecodeFile("/skimages/logo.gif", &bm);
339 // SkImageDecoder::DecodeFile("/beach_shot.JPG", &bm);
340 fBitmap = bm;
341
342 SkRect bounds, texture;
343 texture.set(0, 0, SkIntToScalar(fBitmap.width()),
344 SkIntToScalar(fBitmap.height()));
345 bounds = texture;
346
347 // fMesh.init(bounds, fBitmap.width() / 40, fBitmap.height() / 40, textur e);
348 fMesh.init(bounds, fBitmap.width()/16, fBitmap.height()/16, texture);
349 fOrig = fMesh;
350
351 fP0.set(0, 0);
352 fP1 = fP0;
353
354 fMatrix.setScale(2, 2);
355 fMatrix.invert(&fInverse);
356 }
357
358 protected:
359 // overrides from SkEventSink
360 virtual bool onQuery(SkEvent* evt) {
361 if (SampleCode::TitleQ(*evt)) {
362 SampleCode::TitleR(evt, "Warp");
363 return true;
364 }
365 return this->INHERITED::onQuery(evt);
366 }
367
368 static SkPoint apply_warp(const SkVector& drag, SkScalar dragLength,
369 const SkPoint& dragStart, const SkPoint& dragCurr,
370 const SkPoint& orig) {
371 SkVector delta = orig - dragCurr;
372 SkScalar length = SkPoint::Normalize(&delta);
373 if (length <= kNearlyZero) {
374 return orig;
375 }
376
377 const SkScalar period = 20;
378 const SkScalar mag = dragLength / 3;
379
380 SkScalar d = length / (period);
381 d = mag * SkScalarSin(d) / d;
382 SkScalar dx = delta.fX * d;
383 SkScalar dy = delta.fY * d;
384 SkScalar px = orig.fX + dx;
385 SkScalar py = orig.fY + dy;
386 return SkPoint::Make(px, py);
387 }
388
389 static SkPoint apply_warp2(const SkVector& drag, SkScalar dragLength,
390 const SkPoint& dragStart, const SkPoint& dragCurr,
391 const SkPoint& orig) {
392 SkVector delta = orig - dragCurr;
393 SkScalar length = SkPoint::Normalize(&delta);
394 if (length <= kNearlyZero) {
395 return orig;
396 }
397
398 const SkScalar period = 10 + dragLength/4;
399 const SkScalar mag = dragLength / 3;
400
401 SkScalar d = length / (period);
402 if (d > SK_ScalarPI) {
403 d = SK_ScalarPI;
404 }
405
406 d = -mag * SkScalarSin(d);
407
408 SkScalar dx = delta.fX * d;
409 SkScalar dy = delta.fY * d;
410 SkScalar px = orig.fX + dx;
411 SkScalar py = orig.fY + dy;
412 return SkPoint::Make(px, py);
413 }
414
415 typedef SkPoint (*WarpProc)(const SkVector& drag, SkScalar dragLength,
416 const SkPoint& dragStart, const SkPoint& dragCurr,
417 const SkPoint& orig);
418
419 void warp(const SkPoint& p0, const SkPoint& p1) {
420 WarpProc proc = apply_warp2;
421 SkPoint delta = p1 - p0;
422 SkScalar length = SkPoint::Normalize(&delta);
423 for (int y = 0; y < fMesh.rows(); y++) {
424 for (int x = 0; x < fMesh.cols(); x++) {
425 fMesh.pt(x, y) = proc(delta, length, p0, p1, fOrig.pt(x, y));
426 }
427 }
428 fP0 = p0;
429 fP1 = p1;
430 }
431
432 virtual void onDraw(SkCanvas* canvas) {
433 canvas->drawColor(SK_ColorLTGRAY);
434 // test_bigblur(canvas); return;
435
436 canvas->concat(fMatrix);
437
438 SkPaint paint;
439 paint.setFilterBitmap(true);
440 paint.setShader(SkShader::CreateBitmapShader(fBitmap,
441 SkShader::kClamp_TileMode,
442 SkShader::kClamp_TileMode)) ->unref();
443 fMesh.draw(canvas, paint); //return;
444
445 paint.setShader(NULL);
446 paint.setColor(SK_ColorRED);
447 fMesh.draw(canvas, paint);
448
449 // test_drag(canvas, fBitmap, fP0, fP1);
450 }
451
452 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
453 return new Click(this);
454 }
455
456 virtual bool onClick(Click* click) {
457 SkPoint pts[2] = { click->fOrig, click->fCurr };
458 fInverse.mapPoints(pts, 2);
459 this->warp(pts[0], pts[1]);
460 this->inval(NULL);
461 return true;
462 }
463
464 private:
465 SkIRect fBase, fRect;
466 SkPoint fP0, fP1;
467 typedef SkView INHERITED;
468 };
469
470 //////////////////////////////////////////////////////////////////////////////
471
472 static SkView* MyFactory() { return new WarpView; }
473 static SkViewRegister reg(MyFactory);
OLDNEW
« no previous file with comments | « samplecode/SampleRotateCircles.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698