Home | History | Annotate | Download | only in src
      1 #include "GrMesh.h"
      2 #include "SkCanvas.h"
      3 
      4 GrMesh::GrMesh() : fPts(NULL), fCount(0), fIndices(NULL), fIndexCount(0) {}
      5 
      6 GrMesh::~GrMesh() {
      7     delete[] fPts;
      8     delete[] fIndices;
      9 }
     10 
     11 GrMesh& GrMesh::operator=(const GrMesh& src) {
     12     delete[] fPts;
     13     delete[] fIndices;
     14 
     15     fBounds = src.fBounds;
     16     fRows = src.fRows;
     17     fCols = src.fCols;
     18 
     19     fCount = src.fCount;
     20     fPts = new SkPoint[fCount * 2];
     21     fTex = fPts + fCount;
     22     memcpy(fPts, src.fPts, fCount * 2 * sizeof(SkPoint));
     23 
     24     delete[] fIndices;
     25     fIndexCount = src.fIndexCount;
     26     fIndices = new uint16_t[fIndexCount];
     27     memcpy(fIndices, src.fIndices, fIndexCount * sizeof(uint16_t));
     28 
     29     return *this;
     30 }
     31 
     32 void GrMesh::init(const SkRect& bounds, int rows, int cols,
     33                 const SkRect& texture) {
     34     SkASSERT(rows > 0 && cols > 0);
     35 
     36     fBounds = bounds;
     37     fRows = rows;
     38     fCols = cols;
     39 
     40     delete[] fPts;
     41     fCount = (rows + 1) * (cols + 1);
     42     fPts = new SkPoint[fCount * 2];
     43     fTex = fPts + fCount;
     44 
     45     delete[] fIndices;
     46     fIndexCount = rows * cols * 6;
     47     fIndices = new uint16_t[fIndexCount];
     48 
     49     SkPoint* pts = fPts;
     50     const SkScalar dx = bounds.width() / rows;
     51     const SkScalar dy = bounds.height() / cols;
     52     SkPoint* tex = fTex;
     53     const SkScalar dtx = texture.width() / rows;
     54     const SkScalar dty = texture.height() / cols;
     55     uint16_t* idx = fIndices;
     56     int index = 0;
     57     for (int y = 0; y <= cols; y++) {
     58         for (int x = 0; x <= rows; x++) {
     59             pts->set(bounds.fLeft + x*dx, bounds.fTop + y*dy);
     60             pts += 1;
     61             tex->set(texture.fLeft + x*dtx, texture.fTop + y*dty);
     62             tex += 1;
     63 
     64             if (y < cols && x < rows) {
     65                 *idx++ = index;
     66                 *idx++ = index + rows + 1;
     67                 *idx++ = index + 1;
     68 
     69                 *idx++ = index + 1;
     70                 *idx++ = index + rows + 1;
     71                 *idx++ = index + rows + 2;
     72 
     73                 index += 1;
     74             }
     75         }
     76         index += 1;
     77     }
     78 }
     79 
     80 void GrMesh::draw(SkCanvas* canvas, const SkPaint& paint) {
     81     canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
     82                          fPts, fTex, NULL, NULL, fIndices, fIndexCount,
     83                          paint);
     84 }
     85 
     86 /////////////////////////////////////////////
     87 
     88 #include "SkBoundaryPatch.h"
     89 #include "SkMeshUtils.h"
     90 
     91 static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
     92     return SkPoint::Make(SkScalarInterp(a.fX, b.fX, t),
     93                          SkScalarInterp(a.fY, b.fY, t));
     94 }
     95 
     96 static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
     97                       SkScalar x3, SkScalar y3, SkScalar scale = 1) {
     98     SkPoint tmp, tmp2;
     99 
    100     pts[0].set(x0, y0);
    101     pts[3].set(x3, y3);
    102 
    103     tmp = SkPointInterp(pts[0], pts[3], SK_Scalar1/3);
    104     tmp2 = pts[0] - tmp;
    105     tmp2.rotateCW();
    106     tmp2.scale(scale);
    107     pts[1] = tmp + tmp2;
    108 
    109     tmp = SkPointInterp(pts[0], pts[3], 2*SK_Scalar1/3);
    110     tmp2 = pts[3] - tmp;
    111     tmp2.rotateCW();
    112     tmp2.scale(scale);
    113     pts[2] = tmp + tmp2;
    114 }
    115 
    116 void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) {
    117     const float w = bm.width();
    118     const float h = bm.height();
    119     SkCubicBoundary cubic;
    120     set_cubic(cubic.fPts + 0, 0, 0, w, 0, scale);
    121     set_cubic(cubic.fPts + 3, w, 0, w, h, scale);
    122     set_cubic(cubic.fPts + 6, w, h, 0, h, -scale);
    123     set_cubic(cubic.fPts + 9, 0, h, 0, 0, scale);
    124 
    125     SkBoundaryPatch patch;
    126     patch.setBoundary(&cubic);
    127 
    128     const int Rows = 16;
    129     const int Cols = 16;
    130     SkPoint pts[Rows * Cols];
    131     patch.evalPatch(pts, Rows, Cols);
    132 
    133     SkPaint paint;
    134     paint.setAntiAlias(true);
    135     paint.setFilterBitmap(true);
    136 
    137     SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
    138 }
    139 
    140 
    141