1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #include "SkMeshUtils.h"
9 #include "SkCanvas.h"
10 #include "SkPaint.h"
11 
SkMeshIndices()12 SkMeshIndices::SkMeshIndices() {
13     sk_bzero(this, sizeof(*this));
14 }
15 
~SkMeshIndices()16 SkMeshIndices::~SkMeshIndices() {
17     sk_free(fStorage);
18 }
19 
init(SkPoint tex[],uint16_t indices[],int texW,int texH,int rows,int cols)20 bool SkMeshIndices::init(SkPoint tex[], uint16_t indices[],
21                          int texW, int texH, int rows, int cols) {
22     if (rows < 2 || cols < 2) {
23         sk_free(fStorage);
24         fStorage = NULL;
25         fTex = NULL;
26         fIndices = NULL;
27         fTexCount = fIndexCount = 0;
28         return false;
29     }
30 
31     sk_free(fStorage);
32     fStorage = NULL;
33 
34     fTexCount = rows * cols;
35     rows -= 1;
36     cols -= 1;
37     fIndexCount = rows * cols * 6;
38 
39     if (tex) {
40         fTex = tex;
41         fIndices = indices;
42     } else {
43         fStorage = sk_malloc_throw(fTexCount * sizeof(SkPoint) +
44                                    fIndexCount * sizeof(uint16_t));
45         fTex = (SkPoint*)fStorage;
46         fIndices = (uint16_t*)(fTex + fTexCount);
47     }
48 
49     // compute the indices
50     {
51         uint16_t* idx = fIndices;
52         int index = 0;
53         for (int y = 0; y < cols; y++) {
54             for (int x = 0; x < rows; x++) {
55                 *idx++ = index;
56                 *idx++ = index + rows + 1;
57                 *idx++ = index + 1;
58 
59                 *idx++ = index + 1;
60                 *idx++ = index + rows + 1;
61                 *idx++ = index + rows + 2;
62 
63                 index += 1;
64             }
65             index += 1;
66         }
67     }
68 
69     // compute texture coordinates
70     {
71         SkPoint* tex = fTex;
72         const SkScalar dx = SkIntToScalar(texW) / rows;
73         const SkScalar dy = SkIntToScalar(texH) / cols;
74         for (int y = 0; y <= cols; y++) {
75             for (int x = 0; x <= rows; x++) {
76                 tex->set(x*dx, y*dy);
77                 tex += 1;
78             }
79         }
80     }
81     return true;
82 }
83 
84 ///////////////////////////////////////////////////////////////////////////////
85 
86 #include "SkShader.h"
87 
Draw(SkCanvas * canvas,const SkBitmap & bitmap,int rows,int cols,const SkPoint verts[],const SkColor colors[],const SkPaint & paint)88 void SkMeshUtils::Draw(SkCanvas* canvas, const SkBitmap& bitmap,
89                        int rows, int cols, const SkPoint verts[],
90                        const SkColor colors[], const SkPaint& paint) {
91     SkMeshIndices idx;
92 
93     if (idx.init(bitmap.width(), bitmap.height(), rows, cols)) {
94         SkPaint p(paint);
95         p.setShader(SkShader::CreateBitmapShader(bitmap,
96                                          SkShader::kClamp_TileMode,
97                                          SkShader::kClamp_TileMode))->unref();
98         canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
99                              rows * cols, verts, idx.tex(), colors, NULL,
100                              idx.indices(), idx.indexCount(), p);
101     }
102 }
103