1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SampleCode.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkAnimTimer.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkView.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBitmap.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCornerPathEffect.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGradientShader.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGraphics.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPath.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRandom.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRegion.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShader.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkUtils.h"
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorPriv.h"
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorFilter.h"
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTime.h"
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypeface.h"
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkStream.h"
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorPriv.h"
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkRandom gRand;
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void generate_pts(SkPoint pts[], int count, int w, int h) {
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < count; i++) {
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        pts[i].set(gRand.nextUScalar1() * 3 * w - SkIntToScalar(w),
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   gRand.nextUScalar1() * 3 * h - SkIntToScalar(h));
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool check_zeros(const SkPMColor pixels[], int count, int skip) {
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < count; i++) {
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (*pixels) {
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        pixels += skip;
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return true;
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool check_bitmap_margin(const SkBitmap& bm, int margin) {
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t rb = bm.rowBytes();
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < margin; i++) {
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!check_zeros(bm.getAddr32(0, i), bm.width(), 1)) {
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int bottom = bm.height() - i - 1;
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!check_zeros(bm.getAddr32(0, bottom), bm.width(), 1)) {
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // left column
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!check_zeros(bm.getAddr32(i, 0), bm.height(), SkToInt(rb >> 2))) {
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int right = bm.width() - margin + i;
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!check_zeros(bm.getAddr32(right, 0), bm.height(),
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         SkToInt(rb >> 2))) {
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return false;
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return true;
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define WIDTH   620
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define HEIGHT  460
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define MARGIN  10
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void line_proc(SkCanvas* canvas, const SkPaint& paint,
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const SkBitmap& bm) {
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int N = 2;
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint pts[N];
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 400; i++) {
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        generate_pts(pts, N, WIDTH, HEIGHT);
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawLine(pts[0], pts[1], paint);
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!check_bitmap_margin(bm, MARGIN)) {
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDebugf("---- hairline failure (%g %g) (%g %g)\n",
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                     pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY);
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            break;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void poly_proc(SkCanvas* canvas, const SkPaint& paint,
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const SkBitmap& bm) {
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int N = 8;
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint pts[N];
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 50; i++) {
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        generate_pts(pts, N, WIDTH, HEIGHT);
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPath path;
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(pts[0]);
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int j = 1; j < N; j++) {
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            path.lineTo(pts[j]);
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawPath(path, paint);
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkPoint ave(const SkPoint& a, const SkPoint& b) {
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint c = a + b;
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c.fX = SkScalarHalf(c.fX);
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c.fY = SkScalarHalf(c.fY);
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return c;
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void quad_proc(SkCanvas* canvas, const SkPaint& paint,
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const SkBitmap& bm) {
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int N = 30;
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint pts[N];
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 10; i++) {
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        generate_pts(pts, N, WIDTH, HEIGHT);
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPath path;
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(pts[0]);
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int j = 1; j < N - 2; j++) {
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            path.quadTo(pts[j], ave(pts[j], pts[j+1]));
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.quadTo(pts[N - 2], pts[N - 1]);
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawPath(path, paint);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void add_cubic(SkPath* path, const SkPoint& mid, const SkPoint& end) {
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint start;
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    path->getLastPt(&start);
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    path->cubicTo(ave(start, mid), ave(mid, end), end);
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void cube_proc(SkCanvas* canvas, const SkPaint& paint,
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const SkBitmap& bm) {
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int N = 30;
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint pts[N];
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 10; i++) {
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        generate_pts(pts, N, WIDTH, HEIGHT);
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPath path;
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path.moveTo(pts[0]);
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int j = 1; j < N - 2; j++) {
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            add_cubic(&path, pts[j], ave(pts[j], pts[j+1]));
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        add_cubic(&path, pts[N - 2], pts[N - 1]);
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawPath(path, paint);
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottypedef void (*HairProc)(SkCanvas*, const SkPaint&, const SkBitmap&);
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const struct {
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fName;
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    HairProc    fProc;
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} gProcs[] = {
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { "line",   line_proc },
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { "poly",   poly_proc },
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { "quad",   quad_proc },
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { "cube",   cube_proc },
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic int cycle_hairproc_index(int index) {
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return (index + 1) % SK_ARRAY_COUNT(gProcs);
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass HairlineView : public SampleView {
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMSec fNow;
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fProcIndex;
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fDoAA;
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    HairlineView() {
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fProcIndex = 0;
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fDoAA = true;
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fNow = 0;
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // overrides from SkEventSink
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onQuery(SkEvent* evt) override {
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (SampleCode::TitleQ(*evt)) {
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkString str;
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            str.printf("Hair-%s", gProcs[fProcIndex].fName);
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SampleCode::TitleR(evt, str.c_str());
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->INHERITED::onQuery(evt);
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void show_bitmaps(SkCanvas* canvas, const SkBitmap& b0, const SkBitmap& b1,
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      const SkIRect& inset) {
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawBitmap(b0, 0, 0, nullptr);
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawBitmap(b1, SkIntToScalar(b0.width()), 0, nullptr);
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDrawContent(SkCanvas* canvas) override {
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        gRand.setSeed(fNow);
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkBitmap bm, bm2;
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bm.allocN32Pixels(WIDTH + MARGIN*2, HEIGHT + MARGIN*2);
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // this will erase our margin, which we want to always stay 0
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bm.eraseColor(SK_ColorTRANSPARENT);
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bm2.installPixels(SkImageInfo::MakeN32Premul(WIDTH, HEIGHT),
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                          bm.getAddr32(MARGIN, MARGIN), bm.rowBytes());
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkCanvas c2(bm2);
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setAntiAlias(fDoAA);
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setStyle(SkPaint::kStroke_Style);
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bm2.eraseColor(SK_ColorTRANSPARENT);
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        gProcs[fProcIndex].fProc(&c2, paint, bm);
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawBitmap(bm2, SkIntToScalar(10), SkIntToScalar(10), nullptr);
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onAnimate(const SkAnimTimer&) override {
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fDoAA) {
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fProcIndex = cycle_hairproc_index(fProcIndex);
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // todo: signal that we want to rebuild our TITLE
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fDoAA = !fDoAA;
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return true;
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fDoAA = !fDoAA;
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->INHERITED::onFindClickHandler(x, y, modi);
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SampleView INHERITED;
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//////////////////////////////////////////////////////////////////////////////
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkView* MyFactory() { return new HairlineView; }
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkViewRegister reg(MyFactory);
244