1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7bf0001d0472d727266762c5967ec0d919a6df083reed@google.com
88898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SampleCode.h"
976113a9b7716748c70ea0ecf7aacbabe4cce5009reed#include "SkAnimTimer.h"
108898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkView.h"
118898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkCanvas.h"
128898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkCornerPathEffect.h"
138898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkGradientShader.h"
148898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkGraphics.h"
158898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkPath.h"
168898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkRandom.h"
178898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkRegion.h"
188898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkShader.h"
198898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkUtils.h"
208898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkColorPriv.h"
218898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkColorFilter.h"
228898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkTime.h"
238898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkTypeface.h"
248898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkStream.h"
258898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com#include "SkColorPriv.h"
268898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
278898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comstatic SkRandom gRand;
288898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
298898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comstatic void generate_pts(SkPoint pts[], int count, int w, int h) {
308898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    for (int i = 0; i < count; i++) {
318898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        pts[i].set(gRand.nextUScalar1() * 3 * w - SkIntToScalar(w),
328898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com                   gRand.nextUScalar1() * 3 * h - SkIntToScalar(h));
338898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    }
348898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com}
358898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
368898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comstatic bool check_zeros(const SkPMColor pixels[], int count, int skip) {
378898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    for (int i = 0; i < count; i++) {
388898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        if (*pixels) {
398898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com            return false;
408898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        }
418898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        pixels += skip;
428898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    }
438898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    return true;
448898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com}
458898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
468898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comstatic bool check_bitmap_margin(const SkBitmap& bm, int margin) {
478898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    size_t rb = bm.rowBytes();
488898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    for (int i = 0; i < margin; i++) {
498898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        if (!check_zeros(bm.getAddr32(0, i), bm.width(), 1)) {
508898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com            return false;
518898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        }
528898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        int bottom = bm.height() - i - 1;
538898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        if (!check_zeros(bm.getAddr32(0, bottom), bm.width(), 1)) {
548898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com            return false;
558898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        }
568898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        // left column
577fa2a65c0cfc714364490cb715171461143024e0reed@google.com        if (!check_zeros(bm.getAddr32(i, 0), bm.height(), SkToInt(rb >> 2))) {
588898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com            return false;
598898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        }
608898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        int right = bm.width() - margin + i;
617fa2a65c0cfc714364490cb715171461143024e0reed@google.com        if (!check_zeros(bm.getAddr32(right, 0), bm.height(),
627fa2a65c0cfc714364490cb715171461143024e0reed@google.com                         SkToInt(rb >> 2))) {
638898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com            return false;
648898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        }
658898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    }
668898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    return true;
678898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com}
688898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
6928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com#define WIDTH   620
7028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com#define HEIGHT  460
7128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com#define MARGIN  10
7228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
7328937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic void line_proc(SkCanvas* canvas, const SkPaint& paint,
7428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com                      const SkBitmap& bm) {
7528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    const int N = 2;
7628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    SkPoint pts[N];
7728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    for (int i = 0; i < 400; i++) {
7828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        generate_pts(pts, N, WIDTH, HEIGHT);
7928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
8028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        canvas->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
8128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        if (!check_bitmap_margin(bm, MARGIN)) {
8228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            SkDebugf("---- hairline failure (%g %g) (%g %g)\n",
8328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com                     pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY);
8428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            break;
8528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        }
8628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    }
8728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com}
8828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
8928937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic void poly_proc(SkCanvas* canvas, const SkPaint& paint,
9028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com                      const SkBitmap& bm) {
9128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    const int N = 8;
9228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    SkPoint pts[N];
9328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    for (int i = 0; i < 50; i++) {
9428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        generate_pts(pts, N, WIDTH, HEIGHT);
95ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
9628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        SkPath path;
9728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        path.moveTo(pts[0]);
9828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        for (int j = 1; j < N; j++) {
9928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            path.lineTo(pts[j]);
10028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        }
10128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        canvas->drawPath(path, paint);
10228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    }
10328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com}
10428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
10528937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic SkPoint ave(const SkPoint& a, const SkPoint& b) {
10628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    SkPoint c = a + b;
10728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    c.fX = SkScalarHalf(c.fX);
10828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    c.fY = SkScalarHalf(c.fY);
10928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    return c;
11028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com}
11128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
11228937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic void quad_proc(SkCanvas* canvas, const SkPaint& paint,
11328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com                      const SkBitmap& bm) {
11428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    const int N = 30;
11528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    SkPoint pts[N];
11628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    for (int i = 0; i < 10; i++) {
11728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        generate_pts(pts, N, WIDTH, HEIGHT);
118ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
11928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        SkPath path;
12028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        path.moveTo(pts[0]);
12128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        for (int j = 1; j < N - 2; j++) {
12228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            path.quadTo(pts[j], ave(pts[j], pts[j+1]));
12328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        }
12428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        path.quadTo(pts[N - 2], pts[N - 1]);
125ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
12628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        canvas->drawPath(path, paint);
12728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    }
12828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com}
12928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
13028937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic void add_cubic(SkPath* path, const SkPoint& mid, const SkPoint& end) {
13128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    SkPoint start;
13228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    path->getLastPt(&start);
13328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    path->cubicTo(ave(start, mid), ave(mid, end), end);
13428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com}
13528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
13628937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic void cube_proc(SkCanvas* canvas, const SkPaint& paint,
13728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com                      const SkBitmap& bm) {
13828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    const int N = 30;
13928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    SkPoint pts[N];
14028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    for (int i = 0; i < 10; i++) {
14128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        generate_pts(pts, N, WIDTH, HEIGHT);
142ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
14328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        SkPath path;
14428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        path.moveTo(pts[0]);
14528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        for (int j = 1; j < N - 2; j++) {
14628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            add_cubic(&path, pts[j], ave(pts[j], pts[j+1]));
14728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        }
14828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        add_cubic(&path, pts[N - 2], pts[N - 1]);
149ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
15028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        canvas->drawPath(path, paint);
15128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    }
15228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com}
15328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
15428937283e16928a562b3f9e19908db51bbb89ff9reed@android.comtypedef void (*HairProc)(SkCanvas*, const SkPaint&, const SkBitmap&);
15528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
15628937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic const struct {
15728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    const char* fName;
15828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    HairProc    fProc;
15928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com} gProcs[] = {
16028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    { "line",   line_proc },
16128937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    { "poly",   poly_proc },
16228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    { "quad",   quad_proc },
16328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    { "cube",   cube_proc },
16428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com};
16528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
16628937283e16928a562b3f9e19908db51bbb89ff9reed@android.comstatic int cycle_hairproc_index(int index) {
16728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    return (index + 1) % SK_ARRAY_COUNT(gProcs);
16828937283e16928a562b3f9e19908db51bbb89ff9reed@android.com}
1698898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
1705fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.orgclass HairlineView : public SampleView {
171a3d901099d7d295cd7d9df4114e874d9ccfff447reed@android.com    SkMSec fNow;
17228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    int fProcIndex;
17328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    bool fDoAA;
1748898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.compublic:
175ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com    HairlineView() {
17628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        fProcIndex = 0;
17728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        fDoAA = true;
178a3d901099d7d295cd7d9df4114e874d9ccfff447reed@android.com        fNow = 0;
17928937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    }
180ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1818898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comprotected:
1828898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    // overrides from SkEventSink
18336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onQuery(SkEvent* evt) override {
1848898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        if (SampleCode::TitleQ(*evt)) {
18528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            SkString str;
18628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            str.printf("Hair-%s", gProcs[fProcIndex].fName);
18728937283e16928a562b3f9e19908db51bbb89ff9reed@android.com            SampleCode::TitleR(evt, str.c_str());
1888898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com            return true;
1898898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        }
1908898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        return this->INHERITED::onQuery(evt);
1918898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    }
192ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1938898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    void show_bitmaps(SkCanvas* canvas, const SkBitmap& b0, const SkBitmap& b1,
1948898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com                      const SkIRect& inset) {
19596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        canvas->drawBitmap(b0, 0, 0, nullptr);
19696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        canvas->drawBitmap(b1, SkIntToScalar(b0.width()), 0, nullptr);
1978898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    }
1988898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
19936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDrawContent(SkCanvas* canvas) override {
200a3d901099d7d295cd7d9df4114e874d9ccfff447reed@android.com        gRand.setSeed(fNow);
201ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2028898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        SkBitmap bm, bm2;
203a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org        bm.allocN32Pixels(WIDTH + MARGIN*2, HEIGHT + MARGIN*2);
2048898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        // this will erase our margin, which we want to always stay 0
205dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        bm.eraseColor(SK_ColorTRANSPARENT);
2068898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
207a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org        bm2.installPixels(SkImageInfo::MakeN32Premul(WIDTH, HEIGHT),
20800f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org                          bm.getAddr32(MARGIN, MARGIN), bm.rowBytes());
209ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
2108898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        SkCanvas c2(bm2);
2118898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com        SkPaint paint;
21228937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        paint.setAntiAlias(fDoAA);
21328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        paint.setStyle(SkPaint::kStroke_Style);
21428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
215dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        bm2.eraseColor(SK_ColorTRANSPARENT);
21628937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        gProcs[fProcIndex].fProc(&c2, paint, bm);
21796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        canvas->drawBitmap(bm2, SkIntToScalar(10), SkIntToScalar(10), nullptr);
218d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed    }
219a3d901099d7d295cd7d9df4114e874d9ccfff447reed@android.com
22036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onAnimate(const SkAnimTimer&) override {
221d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        if (fDoAA) {
222d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed            fProcIndex = cycle_hairproc_index(fProcIndex);
223d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed            // todo: signal that we want to rebuild our TITLE
22428937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        }
225d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        fDoAA = !fDoAA;
226d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed        return true;
2278898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com    }
2288898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
22936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
23028937283e16928a562b3f9e19908db51bbb89ff9reed@android.com        fDoAA = !fDoAA;
23196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        this->inval(nullptr);
2324d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        return this->INHERITED::onFindClickHandler(x, y, modi);
23328937283e16928a562b3f9e19908db51bbb89ff9reed@android.com    }
234ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
23528937283e16928a562b3f9e19908db51bbb89ff9reed@android.com
2368898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comprivate:
2375fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    typedef SampleView INHERITED;
2388898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com};
2398898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
2408898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com//////////////////////////////////////////////////////////////////////////////
2418898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.com
2428898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comstatic SkView* MyFactory() { return new HairlineView; }
2438898363b2ee02e36dfa4bb166b59c09c4e835b0freed@android.comstatic SkViewRegister reg(MyFactory);
244