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 */
82ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com#include "SkMeshUtils.h"
92ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com#include "SkCanvas.h"
102ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com#include "SkPaint.h"
112ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
122ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.comSkMeshIndices::SkMeshIndices() {
132ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    sk_bzero(this, sizeof(*this));
142ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com}
152ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
162ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.comSkMeshIndices::~SkMeshIndices() {
172ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    sk_free(fStorage);
182ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com}
192ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
202ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.combool SkMeshIndices::init(SkPoint tex[], uint16_t indices[],
212ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                         int texW, int texH, int rows, int cols) {
222ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    if (rows < 2 || cols < 2) {
232ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        sk_free(fStorage);
242ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fStorage = NULL;
252ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fTex = NULL;
262ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fIndices = NULL;
272ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fTexCount = fIndexCount = 0;
282ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        return false;
292ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    }
302ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
312ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    sk_free(fStorage);
322ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    fStorage = NULL;
332ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
342ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    fTexCount = rows * cols;
352ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    rows -= 1;
362ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    cols -= 1;
372ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    fIndexCount = rows * cols * 6;
382ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
392ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    if (tex) {
402ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fTex = tex;
412ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fIndices = indices;
422ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    } else {
432ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fStorage = sk_malloc_throw(fTexCount * sizeof(SkPoint) +
442ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                                   fIndexCount * sizeof(uint16_t));
452ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fTex = (SkPoint*)fStorage;
462ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        fIndices = (uint16_t*)(fTex + fTexCount);
472ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    }
482ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
492ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    // compute the indices
502ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    {
512ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        uint16_t* idx = fIndices;
522ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        int index = 0;
532ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        for (int y = 0; y < cols; y++) {
542ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com            for (int x = 0; x < rows; x++) {
552ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                *idx++ = index;
562ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                *idx++ = index + rows + 1;
572ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                *idx++ = index + 1;
58d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
592ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                *idx++ = index + 1;
602ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                *idx++ = index + rows + 1;
612ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                *idx++ = index + rows + 2;
62d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
632ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                index += 1;
642ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com            }
652ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com            index += 1;
662ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        }
672ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    }
682ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
692ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    // compute texture coordinates
702ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    {
712ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        SkPoint* tex = fTex;
722ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        const SkScalar dx = SkIntToScalar(texW) / rows;
732ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        const SkScalar dy = SkIntToScalar(texH) / cols;
742ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        for (int y = 0; y <= cols; y++) {
752ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com            for (int x = 0; x <= rows; x++) {
762ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                tex->set(x*dx, y*dy);
772ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                tex += 1;
782ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com            }
792ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        }
802ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    }
812ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    return true;
822ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com}
832ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
842ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com///////////////////////////////////////////////////////////////////////////////
852ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
862ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com#include "SkShader.h"
872ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com
882ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.comvoid SkMeshUtils::Draw(SkCanvas* canvas, const SkBitmap& bitmap,
892ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                       int rows, int cols, const SkPoint verts[],
902ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                       const SkColor colors[], const SkPaint& paint) {
912ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    SkMeshIndices idx;
92d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
932ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    if (idx.init(bitmap.width(), bitmap.height(), rows, cols)) {
942ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        SkPaint p(paint);
952ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        p.setShader(SkShader::CreateBitmapShader(bitmap,
962ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                                         SkShader::kClamp_TileMode,
972ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                                         SkShader::kClamp_TileMode))->unref();
982ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com        canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
992ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                             rows * cols, verts, idx.tex(), colors, NULL,
1002ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com                             idx.indices(), idx.indexCount(), p);
1012ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com    }
1022ee7c640150a863f2859eb0aaf4dfe7ad7836f34reed@android.com}
103