13798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed#include "SkMeshUtils.h"
23798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed#include "SkCanvas.h"
33798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed#include "SkPaint.h"
43798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
53798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkMeshIndices::SkMeshIndices() {
63798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    sk_bzero(this, sizeof(*this));
73798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed}
83798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
93798ac8a1beee1c03d45bde7cf810353829d5f93Mike ReedSkMeshIndices::~SkMeshIndices() {
103798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    sk_free(fStorage);
113798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed}
123798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
133798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reedbool SkMeshIndices::init(SkPoint tex[], uint16_t indices[],
143798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                         int texW, int texH, int rows, int cols) {
153798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    if (rows < 2 || cols < 2) {
163798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        sk_free(fStorage);
173798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fStorage = NULL;
183798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fTex = NULL;
193798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fIndices = NULL;
203798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fTexCount = fIndexCount = 0;
213798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        return false;
223798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    }
233798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
243798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    sk_free(fStorage);
253798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    fStorage = NULL;
263798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
273798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    fTexCount = rows * cols;
283798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    rows -= 1;
293798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    cols -= 1;
303798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    fIndexCount = rows * cols * 6;
313798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
323798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    if (tex) {
333798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fTex = tex;
343798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fIndices = indices;
353798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    } else {
363798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fStorage = sk_malloc_throw(fTexCount * sizeof(SkPoint) +
373798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                                   fIndexCount * sizeof(uint16_t));
383798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fTex = (SkPoint*)fStorage;
393798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        fIndices = (uint16_t*)(fTex + fTexCount);
403798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    }
413798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
423798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    // compute the indices
433798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    {
443798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        uint16_t* idx = fIndices;
453798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        int index = 0;
463798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        for (int y = 0; y < cols; y++) {
473798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed            for (int x = 0; x < rows; x++) {
483798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                *idx++ = index;
493798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                *idx++ = index + rows + 1;
503798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                *idx++ = index + 1;
513798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
523798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                *idx++ = index + 1;
533798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                *idx++ = index + rows + 1;
543798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                *idx++ = index + rows + 2;
553798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
563798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                index += 1;
573798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed            }
583798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed            index += 1;
593798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        }
603798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    }
613798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
623798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    // compute texture coordinates
633798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    {
643798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        SkPoint* tex = fTex;
653798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        const SkScalar dx = SkIntToScalar(texW) / rows;
663798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        const SkScalar dy = SkIntToScalar(texH) / cols;
673798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        for (int y = 0; y <= cols; y++) {
683798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed            for (int x = 0; x <= rows; x++) {
693798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                tex->set(x*dx, y*dy);
703798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                tex += 1;
713798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed            }
723798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        }
733798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    }
743798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    return true;
753798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed}
763798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
773798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed///////////////////////////////////////////////////////////////////////////////
783798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
793798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed#include "SkShader.h"
803798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
813798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reedvoid SkMeshUtils::Draw(SkCanvas* canvas, const SkBitmap& bitmap,
823798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                       int rows, int cols, const SkPoint verts[],
833798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                       const SkColor colors[], const SkPaint& paint) {
843798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    SkMeshIndices idx;
853798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
863798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    if (idx.init(bitmap.width(), bitmap.height(), rows, cols)) {
873798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        SkPaint p(paint);
883798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        p.setShader(SkShader::CreateBitmapShader(bitmap,
893798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                                         SkShader::kClamp_TileMode,
903798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                                         SkShader::kClamp_TileMode))->unref();
913798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed        canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
923798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                             rows * cols, verts, idx.tex(), colors, NULL,
933798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed                             idx.indices(), idx.indexCount(), p);
943798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed    }
953798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed}
963798ac8a1beee1c03d45bde7cf810353829d5f93Mike Reed
97