1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2016 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "gm.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "sk_tool_utils.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkSurface> make_surface(SkCanvas* root, int N, int padLeft, int padTop,
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     int padRight, int padBottom) {
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkImageInfo info = SkImageInfo::MakeN32Premul(N + padLeft + padRight, N + padTop + padBottom);
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return sk_tool_utils::makeSurface(root, info);
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkImage> make_image(SkCanvas* root, int* xDivs, int* yDivs, int padLeft, int padTop,
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                 int padRight, int padBottom) {
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int kCap = 28;
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int kMid = 8;
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const int kSize = 2*kCap + 3*kMid;
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto surface(make_surface(root, kSize, padLeft, padTop, padRight, padBottom));
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCanvas* canvas = surface->getCanvas();
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->translate((float) padLeft, (float) padTop);
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize));
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar strokeWidth = SkIntToScalar(6);
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar radius = SkIntToScalar(kCap) - strokeWidth/2;
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    xDivs[0] = kCap + padLeft;
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    yDivs[0] = kCap + padTop;
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    xDivs[1] = kCap + kMid + padLeft;
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    yDivs[1] = kCap + kMid + padTop;
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    xDivs[2] = kCap + 2 * kMid + padLeft;
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    yDivs[2] = kCap + 2 * kMid + padTop;
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    xDivs[3] = kCap + 3 * kMid + padLeft;
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    yDivs[3] = kCap + 3 * kMid + padTop;
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint paint;
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setAntiAlias(true);
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(0xFFFFFF00);
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRoundRect(r, radius, radius, paint);
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.setXYWH(SkIntToScalar(kCap), 0, SkIntToScalar(kMid), SkIntToScalar(kSize));
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(0x8800FF00);
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.setXYWH(SkIntToScalar(kCap + kMid), 0, SkIntToScalar(kMid), SkIntToScalar(kSize));
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(0x880000FF);
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.setXYWH(SkIntToScalar(kCap + 2*kMid), 0, SkIntToScalar(kMid), SkIntToScalar(kSize));
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(0x88FF00FF);
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.setXYWH(0, SkIntToScalar(kCap), SkIntToScalar(kSize), SkIntToScalar(kMid));
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(0x8800FF00);
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.setXYWH(0, SkIntToScalar(kCap + kMid), SkIntToScalar(kSize), SkIntToScalar(kMid));
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(0x880000FF);
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    r.setXYWH(0, SkIntToScalar(kCap + 2*kMid), SkIntToScalar(kSize), SkIntToScalar(kMid));
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    paint.setColor(0x88FF00FF);
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    canvas->drawRect(r, paint);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return surface->makeImageSnapshot();
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void image_to_bitmap(const SkImage* image, SkBitmap* bm) {
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkImageInfo info = SkImageInfo::MakeN32Premul(image->width(), image->height());
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bm->allocPixels(info);
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    image->readPixels(info, bm->getPixels(), bm->rowBytes(), 0, 0);
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/**
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *  This is similar to NinePatchStretchGM, but it also tests "ninepatch" images with more
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *  than nine patches.
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass LatticeGM : public skiagm::GM {
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    LatticeGM() {}
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("lattice");
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override {
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkISize::Make(800, 800);
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDrawHelper(SkCanvas* canvas, int padLeft, int padTop, int padRight, int padBottom) {
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->save();
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int xDivs[5];
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int yDivs[5];
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        xDivs[0] = padLeft;
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        yDivs[0] = padTop;
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkBitmap bitmap;
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<SkImage> image = make_image(canvas, xDivs + 1, yDivs + 1, padLeft, padTop,
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          padRight, padBottom);
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        image_to_bitmap(image.get(), &bitmap);
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkSize size[] = {
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {  50,  50, }, // shrink in both axes
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            {  50, 200, }, // shrink in X
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { 200,  50, }, // shrink in Y
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { 200, 200, },
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawImage(image, 10, 10, nullptr);
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar x = SkIntToScalar(100);
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar y = SkIntToScalar(100);
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkCanvas::Lattice lattice;
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fXCount = 4;
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fXDivs = xDivs + 1;
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fYCount = 4;
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fYDivs = yDivs + 1;
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fRectTypes = nullptr;
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fColors = nullptr;
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkIRect bounds = SkIRect::MakeLTRB(padLeft, padTop,
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                           image->width() - padRight, image->height() - padBottom);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fBounds = (bounds == SkIRect::MakeWH(image->width(), image->height())) ?
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                nullptr : &bounds;
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int iy = 0; iy < 2; ++iy) {
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int ix = 0; ix < 2; ++ix) {
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                int i = ix * 2 + iy;
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkRect r = SkRect::MakeXYWH(x + ix * 60, y + iy * 60,
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            size[i].width(), size[i].height());
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawBitmapLattice(bitmap, lattice, r);
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Provide hints about 3 solid color rects. These colors match
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // what was already in the bitmap.
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int fixedColorX[3] = {2, 4, 1};
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int fixedColorY[3] = {1, 1, 2};
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkColor fixedColor[3] = {SK_ColorBLACK, SK_ColorBLACK, SK_ColorBLACK};
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType,
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                   kUnpremul_SkAlphaType);
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int rectNum = 0; rectNum < 3; rectNum++) {
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            int srcX = xDivs[fixedColorX[rectNum]-1];
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            int srcY = yDivs[fixedColorY[rectNum]-1];
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            image->readPixels(info, &fixedColor[rectNum], 4, srcX, srcY);
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Include the degenerate first div.  While normally the first patch is "scalable",
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // this will mean that the first non-degenerate patch is "fixed".
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fXCount = 5;
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fXDivs = xDivs;
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fYCount = 5;
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fYDivs = yDivs;
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Let's skip a few rects.
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkCanvas::Lattice::RectType flags[36];
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_bzero(flags, 36 * sizeof(SkCanvas::Lattice::RectType));
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[4] = SkCanvas::Lattice::kTransparent;
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[9] = SkCanvas::Lattice::kTransparent;
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[12] = SkCanvas::Lattice::kTransparent;
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[19] = SkCanvas::Lattice::kTransparent;
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int rectNum = 0; rectNum < 3; rectNum++) {
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            flags[fixedColorY[rectNum]*6 + fixedColorX[rectNum]]
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   = SkCanvas::Lattice::kFixedColor;
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fRectTypes = flags;
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkColor colors[36];
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_bzero(colors, 36 * sizeof(SkColor));
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int rectNum = 0; rectNum < 3; rectNum++) {
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            colors[fixedColorY[rectNum]*6 + fixedColorX[rectNum]]
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   = fixedColor[rectNum];
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fColors = colors;
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(400, 0);
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int iy = 0; iy < 2; ++iy) {
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int ix = 0; ix < 2; ++ix) {
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                int i = ix * 2 + iy;
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkRect r = SkRect::MakeXYWH(x + ix * 60, y + iy * 60,
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            size[i].width(), size[i].height());
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                canvas->drawImageLattice(image.get(), lattice, r);
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->restore();
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->onDrawHelper(canvas, 0, 0, 0, 0);
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(0.0f, 400.0f);
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->onDrawHelper(canvas, 3, 7, 4, 11);
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef skiagm::GM INHERITED;
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new LatticeGM; )
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// LatticeGM2 exercises code paths that draw fixed color and 1x1 rectangles.
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass LatticeGM2 : public skiagm::GM {
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    LatticeGM2() {}
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString onShortName() override {
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkString("lattice2");
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkISize onISize() override {
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkISize::Make(800, 800);
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkImage> makeImage(SkCanvas* root, int padLeft, int padTop, int padRight, int padBottom) {
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const int kSize = 80;
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto surface(make_surface(root, kSize, padLeft, padTop, padRight, padBottom));
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkCanvas* canvas = surface->getCanvas();;
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setAntiAlias(false);
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRect r;
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //first line
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(0, 0, 4, 1);  //4x1 green rect
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFF00FF00);
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(4, 0, 1, 1); //1x1 blue pixel -> draws as rectangle
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFF0000FF);
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(5, 0, kSize-5, 1); //the rest of the line is red
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFFFF0000);
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //second line -> draws as fixed color rectangles
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(0, 1, 4, 1);  //4x1 red rect
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFFFF0000);
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(4, 1, 1, 1); //1x1 blue pixel with alpha
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0x880000FF);
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(5, 1, kSize-5, 1); //the rest of the line is green
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFF00FF00);
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //third line - does not draw, because it is transparent
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(0, 2, 4, kSize-2);  //4x78 green rect
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFF00FF00);
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(4, 2, 1, kSize-2); //1x78 red pixel with alpha
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0x88FF0000);
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r.setXYWH(5, 2, kSize-5, kSize-2); //the rest of the image is blue
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFF0000FF);
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect(r, paint);
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return surface->makeImageSnapshot();
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDrawHelper(SkCanvas* canvas, int padLeft, int padTop, int padRight, int padBottom,
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                      SkPaint& paint) {
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int xDivs[2] = {4, 5};
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int yDivs[2] = {1, 2};
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->save();
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<SkImage> image = makeImage(canvas, padLeft, padTop, padRight, padBottom);
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawImage(image, 10, 10, nullptr);
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkCanvas::Lattice lattice;
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fXCount = 2;
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fXDivs = xDivs;
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fYCount = 2;
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fYDivs = yDivs;
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fBounds = nullptr;
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkCanvas::Lattice::RectType flags[9];
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_bzero(flags, 9 * sizeof(SkCanvas::Lattice::RectType));
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[3] = SkCanvas::Lattice::kFixedColor;
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[4] = SkCanvas::Lattice::kFixedColor;
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[5] = SkCanvas::Lattice::kFixedColor;
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[6] = SkCanvas::Lattice::kTransparent;
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[7] = SkCanvas::Lattice::kTransparent;
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        flags[8] = SkCanvas::Lattice::kTransparent;
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fRectTypes = flags;
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkColor colors[9] = {SK_ColorBLACK, SK_ColorBLACK, SK_ColorBLACK,
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             0xFFFF0000, 0x880000FF, 0xFF00FF00,
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                             SK_ColorBLACK, SK_ColorBLACK, SK_ColorBLACK};
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        lattice.fColors = colors;
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0xFFFFFFFF);
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawImageLattice(image.get(), lattice,
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                 SkRect::MakeXYWH(100, 100, 200, 200), &paint);
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //draw the same content with alpha
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(400, 0);
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0x80000FFF);
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawImageLattice(image.get(), lattice,
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                 SkRect::MakeXYWH(100, 100, 200, 200), &paint);
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->restore();
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(SkCanvas* canvas) override {
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //draw a rectangle in the background with transparent pixels
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setColor(0x7F123456);
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setBlendMode(SkBlendMode::kSrc);
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawRect( SkRect::MakeXYWH(300, 0, 300, 800), paint);
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //draw image lattice with kSrcOver blending
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setBlendMode(SkBlendMode::kSrcOver);
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->onDrawHelper(canvas, 0, 0, 0, 0, paint);
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        //draw image lattice with kSrcATop blending
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->translate(0.0f, 400.0f);
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        paint.setBlendMode(SkBlendMode::kSrcATop);
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->onDrawHelper(canvas, 0, 0, 0, 0, paint);
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef skiagm::GM INHERITED;
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GM( return new LatticeGM2; )
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
342