summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/gm/techtalk1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/gm/techtalk1.cpp')
-rw-r--r--chromium/third_party/skia/gm/techtalk1.cpp397
1 files changed, 397 insertions, 0 deletions
diff --git a/chromium/third_party/skia/gm/techtalk1.cpp b/chromium/third_party/skia/gm/techtalk1.cpp
new file mode 100644
index 00000000000..442d73ba816
--- /dev/null
+++ b/chromium/third_party/skia/gm/techtalk1.cpp
@@ -0,0 +1,397 @@
+
+/*
+ * 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"
+
+#define WIRE_FRAME_WIDTH 1.1f
+
+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(WIRE_FRAME_WIDTH);
+}
+
+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);
+
+ if (showGL) {
+ setGLFrame(&paint);
+ }
+ canvas->drawLine(50, 50, 400, 100, paint);
+ paint.setColor(SK_ColorBLACK);
+
+ 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, 70, 250, 370);
+
+ 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, 70, 250, 370);
+
+ 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:
+ case 3: {
+ SkPath src, dst;
+ src.addOval(r);
+ tesselate(src, &dst);
+ show_fan(canvas, dst, r.centerX(), r.centerY());
+ } break;
+ case 2: {
+ SkPaint p(paint);
+ show_mesh(canvas, r);
+ setGLFrame(&p);
+ paint.setStyle(SkPaint::kFill_Style);
+ canvas->drawCircle(r.centerX(), r.centerY(), 3, p);
+ } 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;
+ case 2: {
+ SkPath path;
+ path.addOval(r);
+ show_glframe(canvas, path);
+ SkScalar rad = paint.getStrokeWidth() / 2;
+ r.outset(rad, rad);
+ show_mesh(canvas, r);
+ } break;
+ case 3: {
+ SkScalar rad = paint.getStrokeWidth() / 2;
+ r.outset(rad, rad);
+ SkPaint paint;
+ paint.setAlpha(0x33);
+ canvas->drawRect(r, paint);
+ show_mesh(canvas, r);
+ } break;
+ }
+ }
+}
+
+#include "SkImageDecoder.h"
+
+static void draw_image(SkCanvas* canvas, bool showGL, int flags) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setFilterBitmap(true);
+ setFade(&paint, showGL);
+
+ static SkBitmap* gBM;
+ if (NULL == gBM) {
+ gBM = new SkBitmap;
+ SkImageDecoder::DecodeFile("/skimages/startrek.png", gBM);
+ }
+ SkRect r = SkRect::MakeWH(gBM->width(), gBM->height());
+
+ canvas->save();
+ canvas->translate(30, 30);
+ canvas->scale(0.8f, 0.8f);
+ canvas->drawBitmap(*gBM, 0, 0, &paint);
+ if (showGL) {
+ show_mesh(canvas, r);
+ }
+ canvas->restore();
+
+ canvas->translate(210, 290);
+ canvas->rotate(-35);
+ canvas->drawBitmap(*gBM, 0, 0, &paint);
+ if (showGL) {
+ show_mesh(canvas, r);
+ }
+}
+
+static void draw_text(SkCanvas* canvas, bool showGL, int flags) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setLCDRenderText(true);
+ const char text[] = "Graphics at Google";
+ size_t len = strlen(text);
+ setFade(&paint, showGL);
+
+ canvas->translate(40, 50);
+ for (int i = 0; i < 10; ++i) {
+ paint.setTextSize(12 + i * 3);
+ canvas->drawText(text, len, 0, 0, paint);
+ if (showGL) {
+ SkRect bounds[256];
+ SkScalar widths[256];
+ int count = paint.getTextWidths(text, len, widths, bounds);
+ SkScalar adv = 0;
+ for (int j = 0; j < count; ++j) {
+ bounds[j].offset(adv, 0);
+ show_mesh(canvas, bounds[j]);
+ adv += widths[j];
+ }
+ }
+ canvas->translate(0, paint.getTextSize() * 3 / 2);
+ }
+}
+
+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) {
+ SkISize size = canvas->getDeviceSize();
+ SkRect dst = SkRect::MakeWH(size.width(), size.height());
+ SkRect src = SkRect::MakeWH(640, 480);
+ SkMatrix matrix;
+ matrix.setRectToRect(src, dst, SkMatrix::kCenter_ScaleToFit);
+
+ canvas->concat(matrix);
+ fProc(canvas, fShowGL, fFlags);
+ }
+
+ virtual uint32_t onGetFlags() const SK_OVERRIDE {
+ return kSkipPDF_Flag | kSkipPicture_Flag | kSkipPipe_Flag | kSkipTiled_Flag;
+ }
+
+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, (2, true, 2))
+ADD_GM(TalkGM, (2, true, 3))
+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);