12e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor/*
22e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor * Copyright 2012 Google Inc.
32e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor *
42e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor * Use of this source code is governed by a BSD-style license that can be
52e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor * found in the LICENSE file.
62e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor */
72e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
82e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SampleCode.h"
92e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkView.h"
102e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkCanvas.h"
112e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkPath.h"
122e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkRegion.h"
132e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkShader.h"
142e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkUtils.h"
152e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkImage.h"
162e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "SkSurface.h"
172e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
1850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#define FAT_PIXEL_COLOR     SK_ColorBLACK
19d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer#define PIXEL_CENTER_SIZE   3
20aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#define WIRE_FRAME_COLOR    0xFFFF0000  /*0xFF00FFFF*/
212e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#define WIRE_FRAME_SIZE     1.5f
222e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
232e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorstatic SkScalar apply_grid(SkScalar x) {
242e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    const SkScalar grid = 2;
252e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    return SkScalarRoundToScalar(x * grid) / grid;
262e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
27011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner
28011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattnerstatic void apply_grid(SkPoint pts[], int count) {
293e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    for (int i = 0; i < count; ++i) {
30011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner        pts[i].set(apply_grid(pts[i].fX), apply_grid(pts[i].fY));
312e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
32011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner}
332a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor
342577743c5650c646fb705df01403707e94f2df04Abramo Bagnarastatic void erase(SkSurface* surface) {
352e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    surface->getCanvas()->clear(SK_ColorTRANSPARENT);
362e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
372e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorstatic SkShader* createChecker(const SkMatrix& localMatrix) {
392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor//    SkColor colors[] = { 0xFFFDFDFD, 0xFFF4F4F4 };
402e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkColor colors[] = { 0xFFFFFFFF, 0xFFFFFFFF };
412e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkBitmap bm;
422e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    bm.allocN32Pixels(2, 2);
432e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    bm.lockPixels();
442e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = SkPreMultiplyColor(colors[0]);
452e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    *bm.getAddr32(0, 1) = *bm.getAddr32(1, 0) = SkPreMultiplyColor(colors[1]);
462e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    return SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
472e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor                                        SkShader::kRepeat_TileMode, &localMatrix);
482e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
492e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
502e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorclass FatBits {
512e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorpublic:
52e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    FatBits() {
532a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor        fAA = false;
543e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        fStyle = kHair_Style;
552a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor        fGrid = true;
562e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fShowSkeleton = true;
572e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fUseGPU = false;
582e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fUseClip = false;
592e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fRectAsOval = false;
602e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fUseTriangle = false;
6151603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor
6251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor        fClipRect.set(2, 2, 11, 8 );
6351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    }
642e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
652e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    int getZoom() const { return fZoom; }
6651603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor
6751603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    bool getAA() const { return fAA; }
6851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    void setAA(bool aa) { fAA = aa; }
692e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
702e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    bool getGrid() const { return fGrid; }
712e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void setGrid(bool g) { fGrid = g; }
722e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
732e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    bool getShowSkeleton() const { return fShowSkeleton; }
742e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void setShowSkeleton(bool ss) { fShowSkeleton = ss; }
752e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
762e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    bool getUseGPU() const { return fUseGPU; }
77e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    void setUseGPU(bool ug) { fUseGPU = ug; }
78e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor
792e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    bool getTriangle() const { return fUseTriangle; }
80e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    void setTriangle(bool ut) { fUseTriangle = ut; }
81e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor
82e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    void toggleRectAsOval() { fRectAsOval = !fRectAsOval; }
832e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
84e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    bool getUseClip() const { return fUseClip; }
85e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    void setUseClip(bool uc) { fUseClip = uc; }
86e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor
872e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    enum Style {
88e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor        kHair_Style,
89e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor        kStroke_Style,
90e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    };
91e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    Style getStyle() const { return fStyle; }
922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void setStyle(Style s) { fStyle = s; }
932e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
942e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void setWHZ(int width, int height, int zoom) {
952e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fW = width;
962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fH = height;
972e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fZoom = zoom;
982e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom));
992e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
1002e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
1012e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fShader.reset(createChecker(fMatrix));
1022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
103e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor        SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1042e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fMinSurface.reset(SkSurface::NewRaster(info));
1052e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        info = info.makeWH(width * zoom, height * zoom);
1062e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fMaxSurface.reset(SkSurface::NewRaster(info));
1072e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
1082e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
1092e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void drawBG(SkCanvas*);
1102e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void drawFG(SkCanvas*);
1112e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void drawLine(SkCanvas*, SkPoint pts[2]);
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    void drawRect(SkCanvas* canvas, SkPoint pts[2]);
1132e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void drawTriangle(SkCanvas* canvas, SkPoint pts[3]);
1142e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
115ac8d75fe94f2aefde5179d53e230b99a1fe1201aChris Lattnerprivate:
1162e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    bool fAA, fGrid, fShowSkeleton, fUseGPU, fUseClip, fRectAsOval, fUseTriangle;
1172e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    Style fStyle;
118e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    int fW, fH, fZoom;
119e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    SkMatrix fMatrix, fInverse;
120e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    SkRect   fBounds, fClipRect;
121e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    SkAutoTUnref<SkShader> fShader;
122ac8d75fe94f2aefde5179d53e230b99a1fe1201aChris Lattner    SkAutoTUnref<SkSurface> fMinSurface;
123e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    SkAutoTUnref<SkSurface> fMaxSurface;
124e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor
1253e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    void setupPaint(SkPaint* paint) {
1263e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        bool aa = this->getAA();
1273e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        switch (fStyle) {
1283e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt            case kHair_Style:
1293e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt                paint->setStrokeWidth(0);
1303e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt                break;
1312e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            case kStroke_Style:
1322e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor                paint->setStrokeWidth(SK_Scalar1);
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                break;
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
1352e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        paint->setAntiAlias(aa);
136e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    }
137e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor
138e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    void setupSkeletonPaint(SkPaint* paint) {
139e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor        paint->setStyle(SkPaint::kStroke_Style);
140e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor        paint->setStrokeWidth(WIRE_FRAME_SIZE);
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        paint->setColor(fShowSkeleton ? WIRE_FRAME_COLOR : 0);
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        paint->setAntiAlias(true);
143e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    }
144e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor
1452e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]);
1462e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void drawLineSkeleton(SkCanvas* max, const SkPoint pts[]);
1473e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    void drawRectSkeleton(SkCanvas* max, const SkRect& r) {
1483e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        SkPaint paint;
1493e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        this->setupSkeletonPaint(&paint);
1503e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        SkPath path;
1513e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt
1523e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        if (fUseGPU && fAA) {
1532e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            SkRect rr = r;
1542e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            rr.inset(SkIntToScalar(fZoom)/2, SkIntToScalar(fZoom)/2);
1552e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            path.addRect(rr);
1562e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            path.moveTo(rr.fLeft, rr.fTop);
1572a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor            path.lineTo(rr.fRight, rr.fBottom);
1582e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            rr = r;
1592def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor            rr.inset(-SkIntToScalar(fZoom)/2, -SkIntToScalar(fZoom)/2);
1602def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor            path.addRect(rr);
161514d3b6b93c83c0841d2f9dd7af8ecc2877fe921Douglas Gregor        } else {
162514d3b6b93c83c0841d2f9dd7af8ecc2877fe921Douglas Gregor            fRectAsOval ? path.addOval(r) : path.addRect(r);
163514d3b6b93c83c0841d2f9dd7af8ecc2877fe921Douglas Gregor            if (fUseGPU) {
164514d3b6b93c83c0841d2f9dd7af8ecc2877fe921Douglas Gregor                path.moveTo(r.fLeft, r.fTop);
165514d3b6b93c83c0841d2f9dd7af8ecc2877fe921Douglas Gregor                path.lineTo(r.fRight, r.fBottom);
166514d3b6b93c83c0841d2f9dd7af8ecc2877fe921Douglas Gregor            }
167514d3b6b93c83c0841d2f9dd7af8ecc2877fe921Douglas Gregor        }
1682def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor        max->drawPath(path, paint);
1692e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
1702e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
1712e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    void copyMinToMax() {
1722e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        erase(fMaxSurface);
1732e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        SkCanvas* canvas = fMaxSurface->getCanvas();
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        canvas->save();
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        canvas->concat(fMatrix);
1762e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fMinSurface->draw(canvas, 0, 0, NULL);
1772e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        canvas->restore();
1782e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
1792e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        SkPaint paint;
18051603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor        paint.setXfermodeMode(SkXfermode::kClear_Mode);
1812e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        for (int iy = 1; iy < fH; ++iy) {
1826ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor            SkScalar y = SkIntToScalar(iy * fZoom);
1836ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor            canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
1846ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor        }
1852def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor        for (int ix = 1; ix < fW; ++ix) {
1862def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor            SkScalar x = SkIntToScalar(ix * fZoom);
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
1892def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor    }
1902def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor};
1912def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor
19291058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattnervoid FatBits::drawBG(SkCanvas* canvas) {
19391058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner    SkPaint paint;
19491058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner
19591058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner    paint.setShader(fShader);
19691058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner    canvas->drawRect(fBounds, paint);
19791058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner    paint.setShader(NULL);
19891058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner}
19991058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid FatBits::drawFG(SkCanvas* canvas) {
2012e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkPaint inner, outer;
2022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    inner.setAntiAlias(true);
20448026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor    inner.setColor(SK_ColorBLACK);
20548026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor    inner.setStrokeWidth(PIXEL_CENTER_SIZE);
20648026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor
20748026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor    outer.setAntiAlias(true);
20848026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor    outer.setColor(SK_ColorWHITE);
20948026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor    outer.setStrokeWidth(PIXEL_CENTER_SIZE + 2);
21048026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor
21148026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor    SkScalar half = SkIntToScalar(fZoom) / 2;
212f6cde77d7bc34bbee26b086ff192637af8e9da59Benjamin Kramer    for (int iy = 0; iy < fH; ++iy) {
21310bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor        SkScalar y = SkIntToScalar(iy * fZoom) + half;
21410bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor        for (int ix = 0; ix < fW; ++ix) {
215f6cde77d7bc34bbee26b086ff192637af8e9da59Benjamin Kramer            SkScalar x = SkIntToScalar(ix * fZoom) + half;
2168cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner
217f6cde77d7bc34bbee26b086ff192637af8e9da59Benjamin Kramer            canvas->drawPoint(x, y, outer);
2182e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            canvas->drawPoint(x, y, inner);
2192e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        }
2202e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22291058ff73fd3b00275348dd4d49f83501dfc0542Chris Lattner    if (fUseClip) {
2232e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        SkPaint p;
224ac8d75fe94f2aefde5179d53e230b99a1fe1201aChris Lattner        p.setStyle(SkPaint::kStroke_Style);
2252e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        p.setColor(SK_ColorLTGRAY);
2262e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        SkRect r = {
2272e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            fClipRect.fLeft * fZoom,
2282e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            fClipRect.fTop * fZoom,
2292e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            fClipRect.fRight * fZoom,
2302e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            fClipRect.fBottom * fZoom
23144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor        };
23244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor        canvas->drawRect(r, p);
23344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
23444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
235a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor
236a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregorvoid FatBits::drawLineSkeleton(SkCanvas* max, const SkPoint pts[]) {
237a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor    SkPaint paint;
238a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor    this->setupSkeletonPaint(&paint);
239a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor
2403e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    SkPath path;
241011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner    path.moveTo(pts[0]);
242011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner    path.lineTo(pts[1]);
243011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner
244011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner    switch (fStyle) {
245011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner        case kHair_Style:
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            if (fUseGPU) {
2472e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor                SkPaint p;
2482e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor                p.setStyle(SkPaint::kStroke_Style);
2492e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor                p.setStrokeWidth(SK_Scalar1 * fZoom);
2502e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor                SkPath dst;
2512e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor                p.getFillPath(path, &dst);
252e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor                path.addPath(dst);
253e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor            }
254e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor            break;
255e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor        case kStroke_Style: {
256e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor            SkPaint p;
2573e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt            p.setStyle(SkPaint::kStroke_Style);
2583e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt            p.setStrokeWidth(SK_Scalar1 * fZoom);
2593e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt            SkPath dst;
2603e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt            p.getFillPath(path, &dst);
2612e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            path = dst;
2622e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
26351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor            if (fUseGPU) {
26451603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor                path.moveTo(dst.getPoint(0));
26551603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor                path.lineTo(dst.getPoint(2));
26651603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor            }
26751603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor        } break;
26851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    }
26951603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor    max->drawPath(path, paint);
2702e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
2712def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor
2722def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregorvoid FatBits::drawLine(SkCanvas* canvas, SkPoint pts[]) {
2732def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor    SkPaint paint;
2742def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor
2752def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor    fInverse.mapPoints(pts, 2);
2762def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor
2772def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor    if (fGrid) {
2782def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor        apply_grid(pts, 2);
2792def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor    }
2802e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
2812e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    erase(fMinSurface);
2822e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    this->setupPaint(&paint);
2832e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    paint.setColor(FAT_PIXEL_COLOR);
2842e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    if (fUseClip) {
2852e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fMinSurface->getCanvas()->save();
2862e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        SkRect r = fClipRect;
2872e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        r.inset(SK_Scalar1/3, SK_Scalar1/3);
2882e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fMinSurface->getCanvas()->clipRect(r, SkRegion::kIntersect_Op, true);
2892e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
2902e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fMinSurface->getCanvas()->drawLine(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, paint);
2912e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    if (fUseClip) {
2922e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fMinSurface->getCanvas()->restore();
2932e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
2942e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    this->copyMinToMax();
2952e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
2962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkCanvas* max = fMaxSurface->getCanvas();
2977fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall
2987fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall    fMatrix.mapPoints(pts, 2);
29970f5bc77dbe4172bde860e15d8b3c29e0d5005cbAnders Carlsson    this->drawLineSkeleton(max, pts);
30070f5bc77dbe4172bde860e15d8b3c29e0d5005cbAnders Carlsson
3012e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fMaxSurface->draw(canvas, 0, 0, NULL);
3022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
3032e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3042e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorvoid FatBits::drawRect(SkCanvas* canvas, SkPoint pts[2]) {
3057fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall    SkPaint paint;
3067fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall
3077fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall    fInverse.mapPoints(pts, 2);
3082e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3092e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    if (fGrid) {
3102e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        apply_grid(pts, 2);
3112e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
3127fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall
3132e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkRect r;
3142e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    r.set(pts, 2);
3152e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3162e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    erase(fMinSurface);
3172e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    this->setupPaint(&paint);
3187fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall    paint.setColor(FAT_PIXEL_COLOR);
3192e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    {
3202e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        SkCanvas* c = fMinSurface->getCanvas();
3212e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        fRectAsOval ? c->drawOval(r, paint) : c->drawRect(r, paint);
3222e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    }
3232e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    this->copyMinToMax();
3247fe0b9ea2c8137c035402e6ea01dfdfbc93214cbJohn McCall
3252e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkCanvas* max = fMaxSurface->getCanvas();
3262e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3272e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fMatrix.mapPoints(pts, 2);
3282e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    r.set(pts, 2);
3292e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    this->drawRectSkeleton(max, r);
3302e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3312e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fMaxSurface->draw(canvas, 0, 0, NULL);
3322e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
3332e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3344ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadvoid FatBits::drawTriangleSkeleton(SkCanvas* max, const SkPoint pts[]) {
3352e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkPaint paint;
336e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    this->setupSkeletonPaint(&paint);
337ac9590effa90406767a544005ed1de52e258306bTed Kremenek
3382e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    SkPath path;
3392e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.moveTo(pts[0]);
3402e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.lineTo(pts[1]);
3412e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.lineTo(pts[2]);
3422e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.close();
3434ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad
3442e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    max->drawPath(path, paint);
3452e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
3462e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3472e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregorvoid FatBits::drawTriangle(SkCanvas* canvas, SkPoint pts[3]) {
348909e58988b3a3bb2ad36bec03aafa1302544fd73John McCall    SkPaint paint;
3492e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3502e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fInverse.mapPoints(pts, 3);
3512e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3522e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    if (fGrid) {
3532e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor        apply_grid(pts, 3);
35450d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    }
35520b3c9dda95e6808865110a21bfec25f95ebcaa7Douglas Gregor
35620b3c9dda95e6808865110a21bfec25f95ebcaa7Douglas Gregor    SkPath path;
3572e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.moveTo(pts[0]);
3582e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.lineTo(pts[1]);
3592e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.lineTo(pts[2]);
3602e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    path.close();
36150d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor
36220b3c9dda95e6808865110a21bfec25f95ebcaa7Douglas Gregor    erase(fMinSurface);
36320b3c9dda95e6808865110a21bfec25f95ebcaa7Douglas Gregor    this->setupPaint(&paint);
3642e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    paint.setColor(FAT_PIXEL_COLOR);
3652e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fMinSurface->getCanvas()->drawPath(path, paint);
3662e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    this->copyMinToMax();
3672e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
36850d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor    SkCanvas* max = fMaxSurface->getCanvas();
3692e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3702e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fMatrix.mapPoints(pts, 3);
3712e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    this->drawTriangleSkeleton(max, pts);
3722e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor
3732e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor    fMaxSurface->draw(canvas, 0, 0, NULL);
3742e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor}
3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor///////////////////////////////////////////////////////////////////////////////////////////////////
377e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor
378e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregorclass IndexClick : public SkView::Click {
379e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor    int fIndex;
380e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregorpublic:
3813e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    IndexClick(SkView* v, int index) : SkView::Click(v), fIndex(index) {}
3823e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt
3833e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt    static int GetIndex(SkView::Click* click) {
3843e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt        return ((IndexClick*)click)->fIndex;
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
3862e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor};
3872577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
3882577743c5650c646fb705df01403707e94f2df04Abramo Bagnaraclass DrawLineView : public SampleView {
3892577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    FatBits fFB;
3902577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    SkPoint fPts[3];
3912577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    bool    fIsRect;
3922577743c5650c646fb705df01403707e94f2df04Abramo Bagnarapublic:
3932577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    DrawLineView() {
3942577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fFB.setWHZ(24, 16, 48);
3952577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fPts[0].set(48, 48);
3962577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fPts[1].set(48 * 5, 48 * 4);
3972577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fPts[2].set(48 * 2, 48 * 6);
3982577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fIsRect = false;
3992577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    }
4002577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
4012577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    void setStyle(FatBits::Style s) {
4022577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fFB.setStyle(s);
4032577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        this->inval(NULL);
4042577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    }
4052577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
4062577743c5650c646fb705df01403707e94f2df04Abramo Bagnaraprotected:
4072577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    virtual bool onQuery(SkEvent* evt) SK_OVERRIDE {
4082577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        if (SampleCode::TitleQ(*evt)) {
4092577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            SampleCode::TitleR(evt, "FatBits");
4102577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            return true;
4112577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        }
4122577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        SkUnichar uni;
4132577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        if (SampleCode::CharQ(*evt, &uni)) {
4142577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            switch (uni) {
4152577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 'c':
4162577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fFB.setUseClip(!fFB.getUseClip());
4172577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    this->inval(NULL);
4182577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4192577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 'r':
4202577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fIsRect = !fIsRect;
4218f0889ce457db51d3af1eb1245bceee272d4dc7dTed Kremenek                    this->inval(NULL);
4222577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4232577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 'o':
4242577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fFB.toggleRectAsOval();
4252577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    this->inval(NULL);
4262577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4272577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 'x':
4282577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fFB.setGrid(!fFB.getGrid());
4292577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    this->inval(NULL);
4302577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4312577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 's':
4322577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    if (FatBits::kStroke_Style == fFB.getStyle()) {
4332577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                        this->setStyle(FatBits::kHair_Style);
4342577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    } else {
4352577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                        this->setStyle(FatBits::kStroke_Style);
4362577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    }
4372577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4382577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 'a':
4392577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fFB.setAA(!fFB.getAA());
4402577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    this->inval(NULL);
4412577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4422577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 'w':
4432577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fFB.setShowSkeleton(!fFB.getShowSkeleton());
4442577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    this->inval(NULL);
4452577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4462577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 'g':
4472577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fFB.setUseGPU(!fFB.getUseGPU());
4482577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    this->inval(NULL);
4492577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4502577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                case 't':
4512577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    fFB.setTriangle(!fFB.getTriangle());
4522577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    this->inval(NULL);
4532577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                    return true;
4542577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            }
4552577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        }
4562577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        return this->INHERITED::onQuery(evt);
4572577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    }
4582577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
4592577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    virtual void onDrawContent(SkCanvas* canvas) {
4602577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fFB.drawBG(canvas);
4612577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        if (fFB.getTriangle()) {
4622577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            fFB.drawTriangle(canvas, fPts);
4632577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        }
4642577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        else if (fIsRect) {
4652577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            fFB.drawRect(canvas, fPts);
4662577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        } else {
4672577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            fFB.drawLine(canvas, fPts);
4682577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        }
4692577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        fFB.drawFG(canvas);
4702577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
4712577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        {
4722577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            SkString str;
4732577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            str.printf("%s %s %s %s",
4742577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                       fFB.getAA() ? "AA" : "BW",
4752577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                       FatBits::kHair_Style == fFB.getStyle() ? "Hair" : "Stroke",
4762577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                       fFB.getUseGPU() ? "GPU" : "CPU",
4772577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                       fFB.getUseClip() ? "clip" : "noclip");
4782577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            SkPaint paint;
4792577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            paint.setAntiAlias(true);
4802577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            paint.setTextSize(16);
4812577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            paint.setColor(SK_ColorBLUE);
4822577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            canvas->drawText(str.c_str(), str.size(), 10, 16, paint);
4832577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        }
4842577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    }
4852577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
4862577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
4872577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                                              unsigned modi) SK_OVERRIDE {
4882577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        SkPoint pt = { x, y };
4892577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        int index = -1;
4902577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        int count = fFB.getTriangle() ? 3 : 2;
4912577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        SkScalar tol = 12;
4922577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
4932577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        for (int i = 0; i < count; ++i) {
4942577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            if (fPts[i].equalsWithinTolerance(pt, tol)) {
4952577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                index = i;
4962577743c5650c646fb705df01403707e94f2df04Abramo Bagnara                break;
4972577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            }
4982577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        }
4992577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        return new IndexClick(this, index);
5002577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    }
5012577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
5022577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    virtual bool onClick(Click* click) SK_OVERRIDE {
5032577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        int index = IndexClick::GetIndex(click);
5042577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        if (index >= 0 && index <= 2) {
5052577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            fPts[index] = click->fCurr;
5062577743c5650c646fb705df01403707e94f2df04Abramo Bagnara        } else {
5072577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            SkScalar dx = click->fCurr.fX - click->fPrev.fX;
5082577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            SkScalar dy = click->fCurr.fY - click->fPrev.fY;
5092577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            fPts[0].offset(dx, dy);
5102577743c5650c646fb705df01403707e94f2df04Abramo Bagnara            fPts[1].offset(dx, dy);
511561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor            fPts[2].offset(dx, dy);
512561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        }
513561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        this->inval(NULL);
514bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor        return true;
515bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    }
516bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
517bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregorprivate:
5182577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
5192577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    typedef SampleView INHERITED;
5202577743c5650c646fb705df01403707e94f2df04Abramo Bagnara};
5212577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
5228cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner//////////////////////////////////////////////////////////////////////////////
5232577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
5242577743c5650c646fb705df01403707e94f2df04Abramo Bagnarastatic SkView* MyFactory() { return new DrawLineView; }
5252577743c5650c646fb705df01403707e94f2df04Abramo Bagnarastatic SkViewRegister reg(MyFactory);
5262577743c5650c646fb705df01403707e94f2df04Abramo Bagnara