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 */
7339cdbfb754ff0837ad4772b4837543e1092d62freed
8d15750c0c7766ecab7022ea9b2f9e89a9132cbc2msarett#include "DecodeFile.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
10339cdbfb754ff0837ad4772b4837543e1092d62freed#include "SkAnimTimer.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h"
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h"
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h"
24887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed#include "SkVertices.h"
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkOSFile.h"
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGeometry.h" // private include :(
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
318a21c9fe7f5fef9e87115defef27bd7218419f28reedstatic sk_sp<SkShader> make_shader0(SkIPoint* size) {
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap    bm;
3382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
34d15750c0c7766ecab7022ea9b2f9e89a9132cbc2msarett//    decode_file("/skimages/progressivejpg.jpg", &bm);
35d15750c0c7766ecab7022ea9b2f9e89a9132cbc2msarett    decode_file("/skimages/logo.png", &bm);
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size->set(bm.width(), bm.height());
378a21c9fe7f5fef9e87115defef27bd7218419f28reed    return SkShader::MakeBitmapShader(bm, SkShader::kClamp_TileMode,
388a21c9fe7f5fef9e87115defef27bd7218419f28reed                                       SkShader::kClamp_TileMode);
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
418a21c9fe7f5fef9e87115defef27bd7218419f28reedstatic sk_sp<SkShader> make_shader1(const SkIPoint& size) {
4264cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org    SkPoint pts[] = { { 0, 0, },
4364cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org                      { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
458a21c9fe7f5fef9e87115defef27bd7218419f28reed    return SkGradientShader::MakeLinear(pts, colors, nullptr,
4683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                    SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode);
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Patch {
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
534516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com    Patch() { sk_bzero(fPts, sizeof(fPts)); }
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ~Patch() {}
5582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setPatch(const SkPoint pts[12]) {
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(fPts, pts, 12 * sizeof(SkPoint));
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPts[12] = pts[0];  // the last shall be first
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setBounds(int w, int h) { fW = w; fH = h; }
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void draw(SkCanvas*, const SkPaint&, int segsU, int segsV,
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com              bool doTextures, bool doColors);
6482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint fPts[13];
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int     fW, fH;
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void eval_patch_edge(const SkPoint cubic[], SkPoint samples[], int segs) {
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar t = 0;
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar dt = SK_Scalar1 / segs;
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    samples[0] = cubic[0];
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 1; i < segs; i++) {
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        t += dt;
7796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkEvalCubicAt(cubic, t, &samples[i], nullptr, nullptr);
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void eval_sheet(const SkPoint edge[], int nu, int nv, int iu, int iv,
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                       SkPoint* pt) {
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int TL = 0;
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int TR = nu;
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int BR = TR + nv;
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int BL = BR + nu;
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar u = SkIntToScalar(iu) / nu;
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar v = SkIntToScalar(iv) / nv;
9082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
91df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar uv = u * v;
92df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar Uv = (1 - u) * v;
93df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar uV = u * (1 - v);
94df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar UV = (1 - u) * (1 - v);
95df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed
96df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar x0 = UV * edge[TL].fX + uV * edge[TR].fX + Uv * edge[BL].fX + uv * edge[BR].fX;
97df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar y0 = UV * edge[TL].fY + uV * edge[TR].fY + Uv * edge[BL].fY + uv * edge[BR].fY;
98df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed
99df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar x = (1 - v) * edge[TL+iu].fX + u * edge[TR+iv].fX +
100df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed                 v * edge[BR+nu-iu].fX + (1 - u) * edge[BL+nv-iv].fX - x0;
101df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed    SkScalar y = (1 - v) * edge[TL+iu].fY + u * edge[TR+iv].fY +
102df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed                 v * edge[BR+nu-iu].fY + (1 - u) * edge[BL+nv-iv].fY - y0;
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    pt->set(x, y);
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkColor make_color(SkScalar s, SkScalar t) {
107e7be3e5c7999230673c8272a2c73cb7261e735c6benjaminwagner    return SkColorSetARGB(0xFF, SkUnitScalarClampToByte(s), SkUnitScalarClampToByte(t), 0);
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Patch::draw(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 bool doTextures, bool doColors) {
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (nu < 1 || nv < 1) {
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int i, npts = (nu + nv) * 2;
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkPoint> storage(npts + 1);
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge0 = storage.get();
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge1 = edge0 + nu;
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge2 = edge1 + nv;
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge3 = edge2 + nu;
12282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // evaluate the edge points
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 0, edge0, nu);
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 3, edge1, nv);
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 6, edge2, nu);
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 9, edge3, nv);
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    edge3[nv] = edge0[0];   // the last shall be first
12982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (i = 0; i < npts; i++) {
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//        canvas->drawLine(edge0[i].fX, edge0[i].fY, edge0[i+1].fX, edge0[i+1].fY, paint);
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
13382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int row, vertCount = (nu + 1) * (nv + 1);
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoTMalloc<SkPoint>  vertStorage(vertCount);
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* verts = vertStorage.get();
13782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // first row
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    memcpy(verts, edge0, (nu + 1) * sizeof(SkPoint));
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // rows
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* r = verts;
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (row = 1; row < nv; row++) {
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r += nu + 1;
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r[0] = edge3[nv - row];
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int col = 1; col < nu; col++) {
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            eval_sheet(edge0, nu, nv, col, row, &r[col]);
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r[nu] = edge1[row];
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // last row
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* last = verts + nv * (nu + 1);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (i = 0; i <= nu; i++) {
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        last[i] = edge2[nu - i];
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
15582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    canvas->drawPoints(verts, vertCount, paint);
15782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int stripCount = (nu + 1) * 2;
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoTMalloc<SkPoint>  stripStorage(stripCount * 2);
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoTMalloc<SkColor>  colorStorage(stripCount);
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* strip = stripStorage.get();
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* tex = strip + stripCount;
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkColor* colors = colorStorage.get();
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar t = 0;
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkScalar ds = SK_Scalar1 * fW / nu;
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkScalar dt = SK_Scalar1 * fH / nv;
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    r = verts;
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (row = 0; row < nv; row++) {
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint* upper = r;
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint* lower = r + nu + 1;
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r = lower;
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar s = 0;
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (i = 0; i <= nu; i++)  {
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            strip[i*2 + 0] = *upper++;
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            strip[i*2 + 1] = *lower++;
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            tex[i*2 + 0].set(s, t);
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            tex[i*2 + 1].set(s, t + dt);
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            colors[i*2 + 0] = make_color(s/fW, t/fH);
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            colors[i*2 + 1] = make_color(s/fW, (t + dt)/fH);
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            s += ds;
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        t += dt;
183887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed        canvas->drawVertices(SkVertices::MakeCopy(SkVertices::kTriangleStrip_VertexMode, stripCount,
184887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed                                                  strip, doTextures ? tex : nullptr,
185887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed                                                  doColors ? colors : nullptr),
186887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed                             SkBlendMode::kModulate, paint);
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void drawpatches(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        Patch* patch) {
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoCanvasRestore ar(canvas, true);
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
194cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed    patch->draw(canvas, paint, nu, nv, false, false);
1956b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    canvas->translate(SkIntToScalar(180), 0);
196cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed    patch->draw(canvas, paint, nu, nv, true, false);
1976b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    canvas->translate(SkIntToScalar(180), 0);
198cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed    patch->draw(canvas, paint, nu, nv, false, true);
1996b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    canvas->translate(SkIntToScalar(180), 0);
200cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed    patch->draw(canvas, paint, nu, nv, true, true);
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
203147476da9eb1577dbdf058edc1164b661347f48dreedconst SkScalar DX = 20;
204147476da9eb1577dbdf058edc1164b661347f48dreedconst SkScalar DY = 0;
205147476da9eb1577dbdf058edc1164b661347f48dreed
2065fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.orgclass PatchView : public SampleView {
207339cdbfb754ff0837ad4772b4837543e1092d62freed    SkScalar    fAngle;
2088a21c9fe7f5fef9e87115defef27bd7218419f28reed    sk_sp<SkShader> fShader0;
2098a21c9fe7f5fef9e87115defef27bd7218419f28reed    sk_sp<SkShader> fShader1;
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIPoint    fSize0, fSize1;
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint     fPts[12];
21282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
21382065d667f64e232bcde2ad849756a6096fcbe6freed@google.compublic:
214339cdbfb754ff0837ad4772b4837543e1092d62freed    PatchView() : fAngle(0) {
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader0 = make_shader0(&fSize0);
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fSize1 = fSize0;
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fSize0.fX == 0 || fSize0.fY == 0) {
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fSize1.set(2, 2);
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader1 = make_shader1(fSize1);
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2226b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        const SkScalar S = SkIntToScalar(50);
2236b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        const SkScalar T = SkIntToScalar(40);
2246b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[0].set(S*0, T);
2256b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[1].set(S*1, T);
2266b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[2].set(S*2, T);
2276b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[3].set(S*3, T);
2286b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[4].set(S*3, T*2);
2296b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[5].set(S*3, T*3);
2306b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[6].set(S*3, T*4);
2316b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[7].set(S*2, T*4);
2326b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[8].set(S*1, T*4);
2336b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[9].set(S*0, T*4);
2346b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[10].set(S*0, T*3);
2356b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[11].set(S*0, T*2);
2365fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org
2375fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org        this->setBGColor(SK_ColorGRAY);
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
23982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // overrides from SkEventSink
242f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein    bool onQuery(SkEvent* evt)  override {
24345369a33bb78b6b76fafd63b1334151368dc9e2atfarina@chromium.org        if (SampleCode::TitleQ(*evt)) {
24445369a33bb78b6b76fafd63b1334151368dc9e2atfarina@chromium.org            SampleCode::TitleR(evt, "Patch");
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::onQuery(evt);
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
24982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
250f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein    void onDrawContent(SkCanvas* canvas) override {
251cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed        const int nu = 10;
252cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed        const int nv = 10;
253cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPaint paint;
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setDither(true);
25693a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        paint.setFilterQuality(kLow_SkFilterQuality);
25782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
258147476da9eb1577dbdf058edc1164b661347f48dreed        canvas->translate(DX, DY);
2596b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Patch   patch;
26182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setShader(fShader0);
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fSize0.fX == 0) {
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fSize0.fX = 1;
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fSize0.fY == 0) {
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fSize0.fY = 1;
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        patch.setBounds(fSize0.fX, fSize0.fY);
27082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
27182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        patch.setPatch(fPts);
272cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed        drawpatches(canvas, paint, nu, nv, &patch);
27382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
27496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        paint.setShader(nullptr);
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAntiAlias(true);
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(SkIntToScalar(5));
277f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(fPts), fPts, paint);
27882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->translate(0, SkIntToScalar(300));
28082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAntiAlias(false);
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setShader(fShader1);
283cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed        if (true) {
2848fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            SkMatrix m;
2858fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            m.setSkew(1, 0);
286150835e779ceb24e2b540f58958cbff2a0ab9942reed            paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
2878fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org        }
288cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed        if (true) {
2898fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            SkMatrix m;
290339cdbfb754ff0837ad4772b4837543e1092d62freed            m.setRotate(fAngle);
291150835e779ceb24e2b540f58958cbff2a0ab9942reed            paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
2928fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org        }
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        patch.setBounds(fSize1.fX, fSize1.fY);
294cdf2db90d97347be41cd32d43cc7ae22ae2dcf3ereed        drawpatches(canvas, paint, nu, nv, &patch);
295339cdbfb754ff0837ad4772b4837543e1092d62freed    }
296b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com
29736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onAnimate(const SkAnimTimer& timer) override {
298339cdbfb754ff0837ad4772b4837543e1092d62freed        fAngle = timer.scaled(60, 360);
299339cdbfb754ff0837ad4772b4837543e1092d62freed        return true;
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
30182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    class PtClick : public Click {
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public:
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int fIndex;
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        PtClick(SkView* view, int index) : Click(view), fIndex(index) {}
3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
30782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
31182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
312f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
313147476da9eb1577dbdf058edc1164b661347f48dreed        x -= DX;
314147476da9eb1577dbdf058edc1164b661347f48dreed        y -= DY;
31564cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org        for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (hittest(fPts[i], x, y)) {
3177fa2a65c0cfc714364490cb715171461143024e0reed@google.com                return new PtClick(this, (int)i);
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3204d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        return this->INHERITED::onFindClickHandler(x, y, modi);
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
32282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
323f059900f75639f1b1a03f2c25333ef9aa22d58b8mtklein    bool onClick(Click* click) override {
324147476da9eb1577dbdf058edc1164b661347f48dreed        fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX - DX, click->fCurr.fY - DY);
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
32782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
3295fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    typedef SampleView INHERITED;
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new PatchView; }
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory);
336