• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "GrMesh.h"
2 #include "SkCanvas.h"
3 
GrMesh()4 GrMesh::GrMesh() : fPts(NULL), fCount(0), fIndices(NULL), fIndexCount(0) {}
5 
~GrMesh()6 GrMesh::~GrMesh() {
7     delete[] fPts;
8     delete[] fIndices;
9 }
10 
operator =(const GrMesh & src)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 
init(const SkRect & bounds,int rows,int cols,const SkRect & texture)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 
draw(SkCanvas * canvas,const SkPaint & paint)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 
SkPointInterp(const SkPoint & a,const SkPoint & b,SkScalar t)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 
set_cubic(SkPoint pts[4],SkScalar x0,SkScalar y0,SkScalar x3,SkScalar y3,SkScalar scale=1)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 
test_patch(SkCanvas * canvas,const SkBitmap & bm,SkScalar scale)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