Home | History | Annotate | Download | only in utils
      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 
     12 SkMeshIndices::SkMeshIndices() {
     13     sk_bzero(this, sizeof(*this));
     14 }
     15 
     16 SkMeshIndices::~SkMeshIndices() {
     17     sk_free(fStorage);
     18 }
     19 
     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 
     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