180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gm.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGeometry.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkShader.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define WIRE_FRAME_WIDTH    1.1f
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void tesselate(const SkPath& src, SkPath* dst) {
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPath::Iter iter(src, true);
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint pts[4];
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPath::Verb verb;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        switch (verb) {
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SkPath::kMove_Verb:
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                dst->moveTo(pts[0]);
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SkPath::kLine_Verb:
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                dst->lineTo(pts[1]);
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                break;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SkPath::kQuad_Verb: {
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPoint p;
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                for (int i = 1; i <= 8; ++i) {
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    SkEvalQuadAt(pts, i / 8.0f, &p, NULL);
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    dst->lineTo(p);
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case SkPath::kCubic_Verb: {
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPoint p;
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                for (int i = 1; i <= 8; ++i) {
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    SkEvalCubicAt(pts, i / 8.0f, &p, NULL, NULL);
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    dst->lineTo(p);
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void setFade(SkPaint* paint, bool showGL) {
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint->setAlpha(showGL ? 0x66 : 0xFF);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void setGLFrame(SkPaint* paint) {
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint->setColor(0xFFFF0000);
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint->setStyle(SkPaint::kStroke_Style);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint->setAntiAlias(true);
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint->setStrokeWidth(WIRE_FRAME_WIDTH);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void show_mesh(SkCanvas* canvas, const SkRect& r) {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setGLFrame(&paint);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawRect(r, paint);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void drawLine(SkCanvas* canvas, const SkPoint& p0, const SkPoint& p1,
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                     const SkPaint& paint) {
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawLine(p0.fX, p0.fY, p1.fX, p1.fY, paint);
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void show_mesh(SkCanvas* canvas, const SkPoint pts[],
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                      const uint16_t indices[], int count) {
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setGLFrame(&paint);
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count - 2; ++i) {
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        drawLine(canvas, pts[indices[i]], pts[indices[i+1]], paint);
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        drawLine(canvas, pts[indices[i+1]], pts[indices[i+2]], paint);
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        drawLine(canvas, pts[indices[i+2]], pts[indices[i]], paint);
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void show_glframe(SkCanvas* canvas, const SkPath& path) {
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setGLFrame(&paint);
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawPath(path, paint);
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void show_mesh_between(SkCanvas* canvas, const SkPath& p0, const SkPath& p1) {
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPath d0, d1;
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tesselate(p0, &d0);
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tesselate(p1, &d1);
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint pts0[256*2], pts1[256];
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = d0.getPoints(pts0, SK_ARRAY_COUNT(pts0));
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count1 = d1.getPoints(pts1, SK_ARRAY_COUNT(pts1));
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count == count1);
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memcpy(&pts0[count], pts1, count * sizeof(SkPoint));
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint16_t indices[256*6];
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint16_t* ndx = indices;
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; ++i) {
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *ndx++ = i;
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *ndx++ = i + count;
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *ndx++ = 0;
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    show_mesh(canvas, pts0, indices, ndx - indices);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void show_fan(SkCanvas* canvas, const SkPath& path, SkScalar cx, SkScalar cy) {
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setGLFrame(&paint);
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawPath(path, paint);
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint pts[256];
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = path.getPoints(pts, SK_ARRAY_COUNT(pts));
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; ++i) {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->drawLine(pts[i].fX, pts[i].fY, cx, cy, paint);
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef void (*DrawProc)(SkCanvas* canvas, bool showGL, int flags);
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void draw_line(SkCanvas* canvas, bool showGL, int flags) {
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        setGLFrame(&paint);
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawLine(50, 50, 400, 100, paint);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setColor(SK_ColorBLACK);
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->rotate(40);
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setFade(&paint, showGL);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setStrokeWidth(40);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawLine(100, 50, 450, 50, paint);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        show_mesh(canvas, SkRect::MakeLTRB(100, 50-20, 450, 50+20));
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void draw_rect(SkCanvas* canvas, bool showGL, int flags) {
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect r = SkRect::MakeLTRB(50, 70, 250, 370);
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setFade(&paint, showGL);
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawRect(r, paint);
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        show_mesh(canvas, r);
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->translate(320, 0);
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setStyle(SkPaint::kStroke_Style);
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setStrokeWidth(25);
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawRect(r, paint);
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar rad = paint.getStrokeWidth() / 2;
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPoint pts[8];
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        r.outset(rad, rad);
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        r.toQuad(&pts[0]);
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        r.inset(rad*2, rad*2);
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        r.toQuad(&pts[4]);
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint16_t indices[] = {
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            0, 4, 1, 5, 2, 6, 3, 7, 0, 4
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        };
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        show_mesh(canvas, pts, indices, SK_ARRAY_COUNT(indices));
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void draw_oval(SkCanvas* canvas, bool showGL, int flags) {
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect r = SkRect::MakeLTRB(50, 70, 250, 370);
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setFade(&paint, showGL);
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawOval(r, paint);
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        switch (flags) {
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 0: {
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPath path;
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                path.addOval(r);
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_glframe(canvas, path);
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 1:
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 3: {
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPath src, dst;
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                src.addOval(r);
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                tesselate(src, &dst);
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_fan(canvas, dst, r.centerX(), r.centerY());
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 2: {
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPaint p(paint);
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_mesh(canvas, r);
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                setGLFrame(&p);
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                paint.setStyle(SkPaint::kFill_Style);
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas->drawCircle(r.centerX(), r.centerY(), 3, p);
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->translate(320, 0);
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setStyle(SkPaint::kStroke_Style);
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setStrokeWidth(25);
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawOval(r, paint);
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        switch (flags) {
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 0: {
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPath path;
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar rad = paint.getStrokeWidth() / 2;
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                r.outset(rad, rad);
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                path.addOval(r);
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                r.inset(rad*2, rad*2);
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                path.addOval(r);
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_glframe(canvas, path);
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 1: {
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPath path0, path1;
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar rad = paint.getStrokeWidth() / 2;
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                r.outset(rad, rad);
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                path0.addOval(r);
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                r.inset(rad*2, rad*2);
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                path1.addOval(r);
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_mesh_between(canvas, path0, path1);
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 2: {
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPath path;
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                path.addOval(r);
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_glframe(canvas, path);
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar rad = paint.getStrokeWidth() / 2;
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                r.outset(rad, rad);
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_mesh(canvas, r);
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            case 3: {
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScalar rad = paint.getStrokeWidth() / 2;
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                r.outset(rad, rad);
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkPaint paint;
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                paint.setAlpha(0x33);
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                canvas->drawRect(r, paint);
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_mesh(canvas, r);
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } break;
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkImageDecoder.h"
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void draw_image(SkCanvas* canvas, bool showGL, int flags) {
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setFilterBitmap(true);
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setFade(&paint, showGL);
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static SkBitmap* gBM;
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == gBM) {
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        gBM = new SkBitmap;
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkImageDecoder::DecodeFile("/skimages/startrek.png", gBM);
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect r = SkRect::MakeWH(gBM->width(), gBM->height());
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->save();
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->translate(30, 30);
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->scale(0.8f, 0.8f);
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawBitmap(*gBM, 0, 0, &paint);
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        show_mesh(canvas, r);
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->restore();
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->translate(210, 290);
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->rotate(-35);
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->drawBitmap(*gBM, 0, 0, &paint);
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (showGL) {
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        show_mesh(canvas, r);
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void draw_text(SkCanvas* canvas, bool showGL, int flags) {
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setLCDRenderText(true);
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char text[] = "Graphics at Google";
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t len = strlen(text);
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    setFade(&paint, showGL);
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->translate(40, 50);
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < 10; ++i) {
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        paint.setTextSize(12 + i * 3);
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->drawText(text, len, 0, 0, paint);
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (showGL) {
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkRect bounds[256];
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScalar widths[256];
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int count = paint.getTextWidths(text, len, widths, bounds);
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScalar adv = 0;
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int j = 0; j < count; ++j) {
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                bounds[j].offset(adv, 0);
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                show_mesh(canvas, bounds[j]);
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                adv += widths[j];
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->translate(0, paint.getTextSize() * 3 / 2);
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const struct {
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    DrawProc    fProc;
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* fName;
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} gRec[] = {
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {   draw_line,  "Lines" },
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {   draw_rect,  "Rects" },
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {   draw_oval,  "Ovals" },
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {   draw_image, "Images" },
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {   draw_text,  "Text" },
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass TalkGM : public skiagm::GM {
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    DrawProc fProc;
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString fName;
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool     fShowGL;
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int      fFlags;
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    TalkGM(int index, bool showGL, int flags = 0) {
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fProc = gRec[index].fProc;
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fName.set(gRec[index].fName);
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (showGL) {
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fName.append("-gl");
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fShowGL = showGL;
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fFlags = flags;
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkString onShortName() {
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fName;
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual SkISize onISize() {
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkISize::Make(640, 480);
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void onDraw(SkCanvas* canvas) {
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkISize size = canvas->getDeviceSize();
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRect dst = SkRect::MakeWH(size.width(), size.height());
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRect src = SkRect::MakeWH(640, 480);
35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMatrix matrix;
35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        matrix.setRectToRect(src, dst, SkMatrix::kCenter_ScaleToFit);
35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        canvas->concat(matrix);
35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fProc(canvas, fShowGL, fFlags);
36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual uint32_t onGetFlags() const SK_OVERRIDE {
36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return  kSkipPDF_Flag | kSkipPicture_Flag | kSkipPipe_Flag | kSkipTiled_Flag;
36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef skiagm::GM INHERITED;
36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////
37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GM_CONCAT(X,Y) GM_CONCAT_IMPL(X,Y)
37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GM_CONCAT_IMPL(X,Y) X##Y
37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define FACTORY_NAME  GM_CONCAT(Factory, __LINE__)
37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define REGISTRY_NAME  GM_CONCAT(gReg, __LINE__)
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define ADD_GM(Class, args)    \
37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static skiagm::GM* FACTORY_NAME(void*) { return new Class args; } \
38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static skiagm::GMRegistry REGISTRY_NAME(FACTORY_NAME);
38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (0, false))
38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (0, true))
38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (1, false))
38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (1, true))
38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (2, false))
38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (2, true))
38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (2, true, 1))
38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (2, true, 2))
39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (2, true, 3))
39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (3, false))
39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (3, true))
39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (4, false))
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruADD_GM(TalkGM, (4, true))
39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//static GM* MyFactory(void*) { return new TalkGM(0, false); }
39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//static GMRegistry reg(MyFactory);
398