1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.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"
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkOSFile.h"
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGeometry.h" // private include :(
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkShader* make_shader0(SkIPoint* size) {
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap    bm;
3282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    SkImageDecoder::DecodeFile("/skimages/progressivejpg.jpg", &bm);
34f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkImageDecoder::DecodeFile("/skimages/logo.png", &bm);
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size->set(bm.width(), bm.height());
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode,
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                        SkShader::kClamp_TileMode);
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkShader* make_shader1(const SkIPoint& size) {
4164cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org    SkPoint pts[] = { { 0, 0, },
4264cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org                      { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkGradientShader::CreateLinear(pts, colors, NULL,
4583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                    SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode);
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Patch {
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
524516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com    Patch() { sk_bzero(fPts, sizeof(fPts)); }
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ~Patch() {}
5482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setPatch(const SkPoint pts[12]) {
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(fPts, pts, 12 * sizeof(SkPoint));
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPts[12] = pts[0];  // the last shall be first
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setBounds(int w, int h) { fW = w; fH = h; }
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void draw(SkCanvas*, const SkPaint&, int segsU, int segsV,
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com              bool doTextures, bool doColors);
6382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint fPts[13];
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int     fW, fH;
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void eval_patch_edge(const SkPoint cubic[], SkPoint samples[], int segs) {
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar t = 0;
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar dt = SK_Scalar1 / segs;
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    samples[0] = cubic[0];
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 1; i < segs; i++) {
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        t += dt;
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkEvalCubicAt(cubic, t, &samples[i], NULL, NULL);
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void eval_sheet(const SkPoint edge[], int nu, int nv, int iu, int iv,
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                       SkPoint* pt) {
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int TL = 0;
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int TR = nu;
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int BR = TR + nv;
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const int BL = BR + nu;
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar u = SkIntToScalar(iu) / nu;
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar v = SkIntToScalar(iv) / nv;
8982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar uv = SkScalarMul(u, v);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar Uv = SkScalarMul(SK_Scalar1 - u, v);
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar uV = SkScalarMul(u, SK_Scalar1 - v);
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar UV = SkScalarMul(SK_Scalar1 - u, SK_Scalar1 - v);
9482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar x0 = SkScalarMul(UV, edge[TL].fX) + SkScalarMul(uV, edge[TR].fX) +
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                  SkScalarMul(Uv, edge[BL].fX) + SkScalarMul(uv, edge[BR].fX);
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar y0 = SkScalarMul(UV, edge[TL].fY) + SkScalarMul(uV, edge[TR].fY) +
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                  SkScalarMul(Uv, edge[BL].fY) + SkScalarMul(uv, edge[BR].fY);
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar x =    SkScalarMul(SK_Scalar1 - v, edge[TL+iu].fX) +
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    SkScalarMul(u, edge[TR+iv].fX) +
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    SkScalarMul(v, edge[BR+nu-iu].fX) +
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    SkScalarMul(SK_Scalar1 - u, edge[BL+nv-iv].fX) - x0;
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar y =    SkScalarMul(SK_Scalar1 - v, edge[TL+iu].fY) +
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    SkScalarMul(u, edge[TR+iv].fY) +
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    SkScalarMul(v, edge[BR+nu-iu].fY) +
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    SkScalarMul(SK_Scalar1 - u, edge[BL+nv-iv].fY) - y0;
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    pt->set(x, y);
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int ScalarTo255(SkScalar v) {
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int scale = SkScalarToFixed(v) >> 8;
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (scale < 0) {
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        scale = 0;
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else if (scale > 255) {
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        scale = 255;
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return scale;
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkColor make_color(SkScalar s, SkScalar t) {
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int cs = ScalarTo255(s);
12382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    int ct = ScalarTo255(t);
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkColorSetARGB(0xFF, cs, 0, 0) + SkColorSetARGB(0, 0, ct, 0);
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Patch::draw(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 bool doTextures, bool doColors) {
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (nu < 1 || nv < 1) {
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int i, npts = (nu + nv) * 2;
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkPoint> storage(npts + 1);
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge0 = storage.get();
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge1 = edge0 + nu;
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge2 = edge1 + nv;
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* edge3 = edge2 + nu;
13982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // evaluate the edge points
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 0, edge0, nu);
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 3, edge1, nv);
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 6, edge2, nu);
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    eval_patch_edge(fPts + 9, edge3, nv);
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    edge3[nv] = edge0[0];   // the last shall be first
14682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (i = 0; i < npts; i++) {
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//        canvas->drawLine(edge0[i].fX, edge0[i].fY, edge0[i+1].fX, edge0[i+1].fY, paint);
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
15082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int row, vertCount = (nu + 1) * (nv + 1);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoTMalloc<SkPoint>  vertStorage(vertCount);
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* verts = vertStorage.get();
15482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // first row
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    memcpy(verts, edge0, (nu + 1) * sizeof(SkPoint));
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // rows
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* r = verts;
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (row = 1; row < nv; row++) {
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r += nu + 1;
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r[0] = edge3[nv - row];
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int col = 1; col < nu; col++) {
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            eval_sheet(edge0, nu, nv, col, row, &r[col]);
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r[nu] = edge1[row];
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // last row
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* last = verts + nv * (nu + 1);
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (i = 0; i <= nu; i++) {
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        last[i] = edge2[nu - i];
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    canvas->drawPoints(verts, vertCount, paint);
17482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int stripCount = (nu + 1) * 2;
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoTMalloc<SkPoint>  stripStorage(stripCount * 2);
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoTMalloc<SkColor>  colorStorage(stripCount);
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* strip = stripStorage.get();
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint* tex = strip + stripCount;
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkColor* colors = colorStorage.get();
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar t = 0;
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkScalar ds = SK_Scalar1 * fW / nu;
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkScalar dt = SK_Scalar1 * fH / nv;
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    r = verts;
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (row = 0; row < nv; row++) {
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint* upper = r;
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint* lower = r + nu + 1;
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r = lower;
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalar s = 0;
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (i = 0; i <= nu; i++)  {
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            strip[i*2 + 0] = *upper++;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            strip[i*2 + 1] = *lower++;
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            tex[i*2 + 0].set(s, t);
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            tex[i*2 + 1].set(s, t + dt);
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            colors[i*2 + 0] = make_color(s/fW, t/fH);
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            colors[i*2 + 1] = make_color(s/fW, (t + dt)/fH);
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            s += ds;
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        t += dt;
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawVertices(SkCanvas::kTriangleStrip_VertexMode, stripCount,
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                             strip, doTextures ? tex : NULL,
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                             doColors ? colors : NULL, NULL,
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                             NULL, 0, paint);
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void drawpatches(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        Patch* patch) {
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoCanvasRestore ar(canvas, true);
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    patch->draw(canvas, paint, 10, 10, false, false);
2136b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    canvas->translate(SkIntToScalar(180), 0);
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    patch->draw(canvas, paint, 10, 10, true, false);
2156b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    canvas->translate(SkIntToScalar(180), 0);
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    patch->draw(canvas, paint, 10, 10, false, true);
2176b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    canvas->translate(SkIntToScalar(180), 0);
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    patch->draw(canvas, paint, 10, 10, true, true);
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2215fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.orgclass PatchView : public SampleView {
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkShader*   fShader0;
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkShader*   fShader1;
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIPoint    fSize0, fSize1;
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint     fPts[12];
22682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
22782065d667f64e232bcde2ad849756a6096fcbe6freed@google.compublic:
228ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com    PatchView() {
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader0 = make_shader0(&fSize0);
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fSize1 = fSize0;
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fSize0.fX == 0 || fSize0.fY == 0) {
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fSize1.set(2, 2);
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader1 = make_shader1(fSize1);
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2366b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        const SkScalar S = SkIntToScalar(50);
2376b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        const SkScalar T = SkIntToScalar(40);
2386b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[0].set(S*0, T);
2396b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[1].set(S*1, T);
2406b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[2].set(S*2, T);
2416b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[3].set(S*3, T);
2426b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[4].set(S*3, T*2);
2436b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[5].set(S*3, T*3);
2446b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[6].set(S*3, T*4);
2456b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[7].set(S*2, T*4);
2466b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[8].set(S*1, T*4);
2476b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[9].set(S*0, T*4);
2486b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[10].set(S*0, T*3);
2496b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        fPts[11].set(S*0, T*2);
2505fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org
2515fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org        this->setBGColor(SK_ColorGRAY);
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
25382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual ~PatchView() {
25582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        SkSafeUnref(fShader0);
25682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        SkSafeUnref(fShader1);
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
25882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // overrides from SkEventSink
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual bool onQuery(SkEvent* evt)  {
26245369a33bb78b6b76fafd63b1334151368dc9e2atfarina@chromium.org        if (SampleCode::TitleQ(*evt)) {
26345369a33bb78b6b76fafd63b1334151368dc9e2atfarina@chromium.org            SampleCode::TitleR(evt, "Patch");
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return this->INHERITED::onQuery(evt);
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
26882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2695fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    virtual void onDrawContent(SkCanvas* canvas) {
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPaint paint;
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setDither(true);
2724469938e92d779dff05e745559e67907bbf21e78reed@google.com        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
27382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2746b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        canvas->translate(SkIntToScalar(20), 0);
2756b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Patch   patch;
27782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setShader(fShader0);
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fSize0.fX == 0) {
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fSize0.fX = 1;
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fSize0.fY == 0) {
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fSize0.fY = 1;
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        patch.setBounds(fSize0.fX, fSize0.fY);
28682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
28782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        patch.setPatch(fPts);
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        drawpatches(canvas, paint, 10, 10, &patch);
28982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setShader(NULL);
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAntiAlias(true);
2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setStrokeWidth(SkIntToScalar(5));
293f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(fPts), fPts, paint);
29482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->translate(0, SkIntToScalar(300));
29682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setAntiAlias(false);
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint.setShader(fShader1);
2998fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org        {
3008fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            SkMatrix m;
3018fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            m.setSkew(1, 0);
3028fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            SkShader* s = SkShader::CreateLocalMatrixShader(paint.getShader(), m);
3038fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            paint.setShader(s)->unref();
3048fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org        }
3058fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org        {
3068fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            static int gAngle;
3078fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            SkMatrix m;
3088fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            m.setRotate(SkIntToScalar(gAngle++));
3098fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            SkShader* s = SkShader::CreateLocalMatrixShader(paint.getShader(), m);
3108fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org            paint.setShader(s)->unref();
3118fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org        }
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        patch.setBounds(fSize1.fX, fSize1.fY);
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        drawpatches(canvas, paint, 10, 10, &patch);
314b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com
3158fae213590981b8ca37839a4e3cae1dae4e611fdcommit-bot@chromium.org        this->inval(NULL);
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
31782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    class PtClick : public Click {
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public:
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int fIndex;
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        PtClick(SkView* view, int index) : Click(view), fIndex(index) {}
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
32382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
32782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3284d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
3294d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                                              unsigned modi) SK_OVERRIDE {
33064cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org        for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (hittest(fPts[i], x, y)) {
3327fa2a65c0cfc714364490cb715171461143024e0reed@google.com                return new PtClick(this, (int)i);
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3354d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        return this->INHERITED::onFindClickHandler(x, y, modi);
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
33782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual bool onClick(Click* click) {
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX, click->fCurr.fY);
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->inval(NULL);
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
34382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
3455fd9243fd6b82aa3f2a2fae7c62310e77ab7b6d3mike@reedtribe.org    typedef SampleView INHERITED;
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new PatchView; }
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory);
352