aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-08 16:52:23 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-08 16:52:23 +0000
commit9f72d5481eab74dfa96ca5914e419994cb2420bf (patch)
treee867f717311bcfb8caea7211c31457b117703d3b
parent7329926f0d70d27495897ab876fc90a8d6687de2 (diff)
experimental
git-svn-id: http://skia.googlecode.com/svn/trunk@5448 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gm/techtalk1.cpp321
1 files changed, 321 insertions, 0 deletions
diff --git a/gm/techtalk1.cpp b/gm/techtalk1.cpp
new file mode 100644
index 0000000000..1b6555520d
--- /dev/null
+++ b/gm/techtalk1.cpp
@@ -0,0 +1,321 @@
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "gm.h"
+
+#include "SkColorPriv.h"
+#include "SkGeometry.h"
+#include "SkShader.h"
+
+static void tesselate(const SkPath& src, SkPath* dst) {
+ SkPath::Iter iter(src, true);
+ SkPoint pts[4];
+ SkPath::Verb verb;
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ dst->moveTo(pts[0]);
+ break;
+ case SkPath::kLine_Verb:
+ dst->lineTo(pts[1]);
+ break;
+ case SkPath::kQuad_Verb: {
+ SkPoint p;
+ for (int i = 1; i <= 8; ++i) {
+ SkEvalQuadAt(pts, i / 8.0f, &p, NULL);
+ dst->lineTo(p);
+ }
+ } break;
+ case SkPath::kCubic_Verb: {
+ SkPoint p;
+ for (int i = 1; i <= 8; ++i) {
+ SkEvalCubicAt(pts, i / 8.0f, &p, NULL, NULL);
+ dst->lineTo(p);
+ }
+ } break;
+ }
+ }
+}
+
+static void setFade(SkPaint* paint, bool showGL) {
+ paint->setAlpha(showGL ? 0x66 : 0xFF);
+}
+
+static void setGLFrame(SkPaint* paint) {
+ paint->setColor(0xFFFF0000);
+ paint->setStyle(SkPaint::kStroke_Style);
+ paint->setAntiAlias(true);
+ paint->setStrokeWidth(1.1f);
+}
+
+static void show_mesh(SkCanvas* canvas, const SkRect& r) {
+ SkPaint paint;
+ setGLFrame(&paint);
+
+ canvas->drawRect(r, paint);
+ canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
+}
+
+static void drawLine(SkCanvas* canvas, const SkPoint& p0, const SkPoint& p1,
+ const SkPaint& paint) {
+ canvas->drawLine(p0.fX, p0.fY, p1.fX, p1.fY, paint);
+}
+
+static void show_mesh(SkCanvas* canvas, const SkPoint pts[],
+ const uint16_t indices[], int count) {
+ SkPaint paint;
+ setGLFrame(&paint);
+
+ for (int i = 0; i < count - 2; ++i) {
+ drawLine(canvas, pts[indices[i]], pts[indices[i+1]], paint);
+ drawLine(canvas, pts[indices[i+1]], pts[indices[i+2]], paint);
+ drawLine(canvas, pts[indices[i+2]], pts[indices[i]], paint);
+ }
+}
+
+static void show_glframe(SkCanvas* canvas, const SkPath& path) {
+ SkPaint paint;
+ setGLFrame(&paint);
+ canvas->drawPath(path, paint);
+}
+
+static void show_mesh_between(SkCanvas* canvas, const SkPath& p0, const SkPath& p1) {
+ SkPath d0, d1;
+ tesselate(p0, &d0);
+ tesselate(p1, &d1);
+
+ SkPoint pts0[256*2], pts1[256];
+ int count = d0.getPoints(pts0, SK_ARRAY_COUNT(pts0));
+ int count1 = d1.getPoints(pts1, SK_ARRAY_COUNT(pts1));
+ SkASSERT(count == count1);
+ memcpy(&pts0[count], pts1, count * sizeof(SkPoint));
+
+ uint16_t indices[256*6];
+ uint16_t* ndx = indices;
+ for (int i = 0; i < count; ++i) {
+ *ndx++ = i;
+ *ndx++ = i + count;
+ }
+ *ndx++ = 0;
+
+ show_mesh(canvas, pts0, indices, ndx - indices);
+}
+
+static void show_fan(SkCanvas* canvas, const SkPath& path, SkScalar cx, SkScalar cy) {
+ SkPaint paint;
+ setGLFrame(&paint);
+
+ canvas->drawPath(path, paint);
+
+ SkPoint pts[256];
+ int count = path.getPoints(pts, SK_ARRAY_COUNT(pts));
+ for (int i = 0; i < count; ++i) {
+ canvas->drawLine(pts[i].fX, pts[i].fY, cx, cy, paint);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef void (*DrawProc)(SkCanvas* canvas, bool showGL, int flags);
+
+static void draw_line(SkCanvas* canvas, bool showGL, int flags) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ canvas->drawLine(50, 50, 400, 100, paint);
+
+ canvas->rotate(40);
+ setFade(&paint, showGL);
+ paint.setStrokeWidth(40);
+ canvas->drawLine(100, 50, 450, 50, paint);
+ if (showGL) {
+ show_mesh(canvas, SkRect::MakeLTRB(100, 50-20, 450, 50+20));
+ }
+}
+
+static void draw_rect(SkCanvas* canvas, bool showGL, int flags) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ SkRect r = SkRect::MakeLTRB(50, 50, 250, 350);
+
+ setFade(&paint, showGL);
+ canvas->drawRect(r, paint);
+ if (showGL) {
+ show_mesh(canvas, r);
+ }
+
+ canvas->translate(320, 0);
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(25);
+ canvas->drawRect(r, paint);
+ if (showGL) {
+ SkScalar rad = paint.getStrokeWidth() / 2;
+ SkPoint pts[8];
+ r.outset(rad, rad);
+ r.toQuad(&pts[0]);
+ r.inset(rad*2, rad*2);
+ r.toQuad(&pts[4]);
+
+ const uint16_t indices[] = {
+ 0, 4, 1, 5, 2, 6, 3, 7, 0, 4
+ };
+ show_mesh(canvas, pts, indices, SK_ARRAY_COUNT(indices));
+ }
+}
+
+static void draw_oval(SkCanvas* canvas, bool showGL, int flags) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ SkRect r = SkRect::MakeLTRB(50, 50, 250, 350);
+
+ setFade(&paint, showGL);
+ canvas->drawOval(r, paint);
+ if (showGL) {
+ switch (flags) {
+ case 0: {
+ SkPath path;
+ path.addOval(r);
+ show_glframe(canvas, path);
+ } break;
+ case 1: {
+ SkPath src, dst;
+ src.addOval(r);
+ tesselate(src, &dst);
+ show_fan(canvas, dst, r.centerX(), r.centerY());
+ } break;
+ }
+ }
+
+ canvas->translate(320, 0);
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(25);
+ canvas->drawOval(r, paint);
+ if (showGL) {
+ switch (flags) {
+ case 0: {
+ SkPath path;
+ SkScalar rad = paint.getStrokeWidth() / 2;
+ r.outset(rad, rad);
+ path.addOval(r);
+ r.inset(rad*2, rad*2);
+ path.addOval(r);
+ show_glframe(canvas, path);
+ } break;
+ case 1: {
+ SkPath path0, path1;
+ SkScalar rad = paint.getStrokeWidth() / 2;
+ r.outset(rad, rad);
+ path0.addOval(r);
+ r.inset(rad*2, rad*2);
+ path1.addOval(r);
+ show_mesh_between(canvas, path0, path1);
+ } break;
+ }
+ }
+}
+
+static void draw_image(SkCanvas* canvas, bool showGL, int flags) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ canvas->drawLine(10, 10, 400, 30, paint);
+ paint.setStrokeWidth(10);
+ canvas->drawLine(50, 50, 400, 400, paint);
+}
+
+static void draw_text(SkCanvas* canvas, bool showGL, int flags) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ canvas->drawLine(10, 10, 400, 30, paint);
+ paint.setStrokeWidth(10);
+ canvas->drawLine(50, 50, 400, 400, paint);
+}
+
+static const struct {
+ DrawProc fProc;
+ const char* fName;
+} gRec[] = {
+ { draw_line, "Lines" },
+ { draw_rect, "Rects" },
+ { draw_oval, "Ovals" },
+ { draw_image, "Images" },
+ { draw_text, "Text" },
+};
+
+class TalkGM : public skiagm::GM {
+ DrawProc fProc;
+ SkString fName;
+ bool fShowGL;
+ int fFlags;
+
+public:
+ TalkGM(int index, bool showGL, int flags = 0) {
+ fProc = gRec[index].fProc;
+ fName.set(gRec[index].fName);
+ if (showGL) {
+ fName.append("-gl");
+ }
+ fShowGL = showGL;
+ fFlags = flags;
+ }
+
+protected:
+ virtual SkString onShortName() {
+ return fName;
+ }
+
+ virtual SkISize onISize() {
+ return SkISize::Make(640, 480);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) {
+ SkRect dst = SkRect::MakeWH(canvas->getDevice()->width(), canvas->getDevice()->height());
+ SkRect src = SkRect::MakeWH(640, 480);
+ SkMatrix matrix;
+ matrix.setRectToRect(src, dst, SkMatrix::kCenter_ScaleToFit);
+
+ canvas->concat(matrix);
+ fProc(canvas, fShowGL, fFlags);
+ }
+
+private:
+ typedef skiagm::GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+#define GM_CONCAT(X,Y) GM_CONCAT_IMPL(X,Y)
+#define GM_CONCAT_IMPL(X,Y) X##Y
+
+#define FACTORY_NAME GM_CONCAT(Factory, __LINE__)
+#define REGISTRY_NAME GM_CONCAT(gReg, __LINE__)
+
+#define ADD_GM(Class, args) \
+ static skiagm::GM* FACTORY_NAME(void*) { return new Class args; } \
+ static skiagm::GMRegistry REGISTRY_NAME(FACTORY_NAME);
+
+ADD_GM(TalkGM, (0, false))
+ADD_GM(TalkGM, (0, true))
+ADD_GM(TalkGM, (1, false))
+ADD_GM(TalkGM, (1, true))
+ADD_GM(TalkGM, (2, false))
+ADD_GM(TalkGM, (2, true))
+ADD_GM(TalkGM, (2, true, 1))
+ADD_GM(TalkGM, (3, false))
+ADD_GM(TalkGM, (3, true))
+ADD_GM(TalkGM, (4, false))
+ADD_GM(TalkGM, (4, true))
+
+//static GM* MyFactory(void*) { return new TalkGM(0, false); }
+//static GMRegistry reg(MyFactory);
+
+