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