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