Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/effects/gradients/SkMeshGradient.cpp

Issue 451723003: SkPatchGrid interface (after SkPatch/SkPicture rebase). (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkMeshGradient.h"
9 #include "SkPatchUtils.h"
10
11 SkMeshGradient::SkMeshGradient(int rows, int cols)
12 : fRows(rows)
13 , fCols(cols)
14 , fCornerPts(NULL)
15 , fCornerColors(NULL)
16 , fHrzCtrlPts(NULL)
17 , fVrtCtrlPts(NULL) {
18 this->reset(fRows, fCols, NULL, NULL, NULL, NULL);
19 }
20
21 SkMeshGradient::SkMeshGradient(int rows, int cols, const SkPoint* corners,
22 const SkPoint* hrzCtrlPts, const SkPoint* vrtCtrl Pts,
23 const SkColor* colors)
24 : fRows(rows)
25 , fCols(cols)
26 , fCornerPts(NULL)
27 , fCornerColors(NULL)
28 , fHrzCtrlPts(NULL)
29 , fVrtCtrlPts(NULL) {
30 this->reset(fRows, fCols, corners, hrzCtrlPts, vrtCtrlPts, colors);
31 }
32
33 SkMeshGradient::~SkMeshGradient() {
34 SkDELETE_ARRAY(fCornerPts);
35 SkDELETE_ARRAY(fCornerColors);
36 SkDELETE_ARRAY(fHrzCtrlPts);
37 SkDELETE_ARRAY(fVrtCtrlPts);
38 }
39
40 bool SkMeshGradient::addPatch(int x, int y, const SkPoint ctrlPts[12], const SkC olor colors[4]) {
41 // Check for the passed paramaters to be within the range of the mesh gradie nt dimensions.
42 if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1) {
43 return false;
44 }
45
46 //setup corners and colors
47 int cornerPos = y * (fCols + 1) + x;
48 fCornerPts[cornerPos] = ctrlPts[SkPatch::kTopP0_CubicCtrlPts];
49 fCornerPts[cornerPos + 1] = ctrlPts[SkPatch::kTopP3_CubicCtrlPts];
50 fCornerPts[cornerPos + (fCols + 1)] = ctrlPts[SkPatch::kBottomP0_CubicCtrlPt s];
51 fCornerPts[cornerPos + (fCols + 1) + 1] = ctrlPts[SkPatch::kBottomP3_CubicCt rlPts];
52
53 fCornerColors[cornerPos] = colors[0];
54 fCornerColors[cornerPos + 1] = colors[1];
55 fCornerColors[cornerPos + (fCols + 1)] = colors[3];
56 fCornerColors[cornerPos + (fCols + 1) + 1] = colors[2];
57
58 // set horizontal control points
59 int hrzPos = y * (fCols * 2) + (x * 2);
60 fHrzCtrlPts[hrzPos] = ctrlPts[SkPatch::kTopP1_CubicCtrlPts];
61 fHrzCtrlPts[hrzPos + 1] = ctrlPts[SkPatch::kTopP2_CubicCtrlPts];
62 fHrzCtrlPts[hrzPos + (fCols * 2)] = ctrlPts[SkPatch::kBottomP1_CubicCtrlPts] ;
63 fHrzCtrlPts[hrzPos + (fCols * 2) + 1] = ctrlPts[SkPatch::kBottomP2_CubicCtrl Pts];
64
65 int vrtPos = (y*2) * (fCols + 1) + x;
66 fVrtCtrlPts[vrtPos] = ctrlPts[SkPatch::kLeftP1_CubicCtrlPts];
67 fVrtCtrlPts[vrtPos + 1] = ctrlPts[SkPatch::kRightP1_CubicCtrlPts];
68 fVrtCtrlPts[vrtPos + (fCols + 1)] = ctrlPts[SkPatch::kLeftP2_CubicCtrlPts];
69 fVrtCtrlPts[vrtPos + (fCols + 1) + 1] = ctrlPts[SkPatch::kRightP2_CubicCtrlP ts];
70 return true;
71 }
72
73 bool SkMeshGradient::addPatch(int x, int y, const SkPatch& patch) {
74 return this->addPatch(x, y, patch.getControlPoints(), patch.getColors());
75 }
76
77 void SkMeshGradient::getPatchAt(int x, int y, SkPatch* patch) const {
78
79 if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1) {
80 return;
81 }
82
83 if (NULL != patch) {
84 //set the patch by building the array of points and colors with the corr esponding values.
85
86 SkPoint ctrlPts[12];
87 SkColor colors[4];
88
89 int cornerPos = y * (fCols + 1) + x;
90 ctrlPts[SkPatch::kTopP0_CubicCtrlPts] = fCornerPts[cornerPos];
91 ctrlPts[SkPatch::kTopP3_CubicCtrlPts] = fCornerPts[cornerPos + 1];
92 ctrlPts[SkPatch::kBottomP0_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1)];
93 ctrlPts[SkPatch::kBottomP3_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1) + 1];
94
95 colors[0] = fCornerColors[cornerPos];
96 colors[1] = fCornerColors[cornerPos + 1];
97 colors[3] = fCornerColors[cornerPos + (fCols + 1)];
98 colors[2] = fCornerColors[cornerPos + (fCols + 1) + 1];
99
100 int hrzPos = y * (fCols * 2) + (x * 2);
101 ctrlPts[SkPatch::kTopP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos];
102 ctrlPts[SkPatch::kTopP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + 1];
103 ctrlPts[SkPatch::kBottomP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2)];
104 ctrlPts[SkPatch::kBottomP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2) + 1];
105
106 int vrtPos = (y*2) * (fCols + 1) + x;
107 ctrlPts[SkPatch::kLeftP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos];
108 ctrlPts[SkPatch::kRightP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos + 1];
109 ctrlPts[SkPatch::kLeftP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1 )];
110 ctrlPts[SkPatch::kRightP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1) + 1];
111
112 patch->reset(ctrlPts, colors);
113 }
114 }
115
116 void SkMeshGradient::resize(int rows, int cols) {
117 //save old values
118 int oldCols = fCols;
119 int oldRows = fRows;
120
121 fCols = cols;
122 fRows = rows;
123
124 SkPoint* pts = fCornerPts;
125 SkColor* colors = fCornerColors;
126 SkPoint* hzrPts = fHrzCtrlPts;
127 SkPoint* vrtPts = fVrtCtrlPts;
128
129 fCornerPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * (fCols + 1));
130 fCornerColors = SkNEW_ARRAY(SkColor, (fRows + 1) * (fCols + 1));
131 fHrzCtrlPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * fCols * 2);
132 fVrtCtrlPts = SkNEW_ARRAY(SkPoint, fRows * 2 * (fCols + 1));
133
134 //copy previous values that are still within the new range.
135 for (int y = 0; y < fRows; y++) {
136 for (int x = 0; x < fCols; x++) {
137 if (x >= oldCols || y >= oldRows) {
138 continue;
139 }
140
141 int cornerPos = y * (fCols + 1) + x;
142 int oldCornerPos = y * (oldCols + 1) + x;
143 fCornerPts[cornerPos] = pts[oldCornerPos];
144 fCornerPts[cornerPos + 1] = pts[oldCornerPos + 1];
145 fCornerPts[cornerPos + (fCols + 1)] = pts[oldCornerPos + (oldCols + 1)];
146 fCornerPts[cornerPos + (fCols + 1) + 1] = pts[oldCornerPos + (oldCol s + 1) + 1];
147 fCornerColors[cornerPos] = colors[oldCornerPos];
148 fCornerColors[cornerPos + 1] = colors[oldCornerPos + 1];
149 fCornerColors[cornerPos + (fCols + 1)] = colors[oldCornerPos + (oldC ols + 1)];
150 fCornerColors[cornerPos + (fCols + 1) + 1] =
151 colors[oldCornerPos + (oldCo ls + 1) + 1];
152
153 int hrzPos = y * (fCols * 2) + (x * 2);
154 int oldHrzPos = y * (oldCols * 2) + (x * 2);
155 fHrzCtrlPts[hrzPos] = hzrPts[oldHrzPos];
156 fHrzCtrlPts[hrzPos + 1] = hzrPts[oldHrzPos + 1];
157 fHrzCtrlPts[hrzPos + (fCols * 2)] = hzrPts[oldHrzPos + (oldCols * 2) ];
158 fHrzCtrlPts[hrzPos + (fCols * 2) + 1] = hzrPts[oldHrzPos + (oldCols * 2) + 1];
159
160 int vrtPos = (y*2) * (fCols + 1) + x;
161 int oldVrtPos = (y*2) * (oldCols + 1) + x;
162 fVrtCtrlPts[vrtPos] = vrtPts[oldVrtPos];
163 fVrtCtrlPts[vrtPos + 1] = vrtPts[oldVrtPos + 1];
164 fVrtCtrlPts[vrtPos + (fCols + 1)] = vrtPts[oldVrtPos + (oldCols + 1) ];
165 fVrtCtrlPts[vrtPos + (fCols + 1) + 1] = vrtPts[oldVrtPos + (oldCols + 1) + 1];
166 }
167 }
168
169 //delete old copies.
170 SkDELETE_ARRAY(pts);
171 SkDELETE_ARRAY(colors);
172 SkDELETE_ARRAY(hzrPts);
173 SkDELETE_ARRAY(vrtPts);
174 }
175
176 void SkMeshGradient::reset(int rows, int cols, const SkPoint* corners, const SkP oint* hrzCtrlPts,
177 const SkPoint* vrtCtrlPts, const SkColor* colors) {
178 SkDELETE_ARRAY(fCornerPts);
179 SkDELETE_ARRAY(fCornerColors);
180 SkDELETE_ARRAY(fHrzCtrlPts);
181 SkDELETE_ARRAY(fVrtCtrlPts);
182
183 fCols = cols;
184 fRows = rows;
185
186 fCornerPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * (fCols + 1));
187 fCornerColors = SkNEW_ARRAY(SkColor, (fRows + 1) * (fCols + 1));
188 fHrzCtrlPts = SkNEW_ARRAY(SkPoint, (fRows + 1) * fCols * 2);
189 fVrtCtrlPts = SkNEW_ARRAY(SkPoint, fRows * 2 * (fCols + 1));
190
191 if (NULL != corners) {
192 memcpy(fCornerPts, corners, (fRows + 1) * (fCols + 1) * sizeof(SkPoint)) ;
193 }
194 if (NULL != colors) {
195 memcpy(fCornerColors, colors, (fRows + 1) * (fCols + 1) * sizeof(SkColor ));
196 }
197 if (NULL != hrzCtrlPts) {
198 memcpy(fHrzCtrlPts, hrzCtrlPts, (fRows + 1) * fCols * 2 * sizeof(SkPoint ));
199 }
200 if (NULL != vrtCtrlPts) {
201 memcpy(fVrtCtrlPts, vrtCtrlPts, fRows * 2 * (fCols + 1) * sizeof(SkPoint ));
202 }
203 }
204
205 void SkMeshGradient::draw(SkCanvas* canvas, SkPaint& paint) {
206 int* maxCols = SkNEW_ARRAY(int, fCols);
207 int* maxRows = SkNEW_ARRAY(int, fRows);
208 memset(maxCols, 0, fCols*sizeof(int));
209 memset(maxRows, 0, fRows*sizeof(int));
210
211 // Get the maximum level of detail per axis for each row and column
212 for (int y = 0; y < fRows; y++) {
213 for (int x = 0; x < fCols; x++) {
214 SkPatch patch;
215 this->getPatchAt(x, y, &patch);
216 SkMatrix matrix = canvas->getTotalMatrix();
217 SkISize lod = SkPatchUtils::GetLevelOfDetail(patch, &matrix);
218 maxCols[x] = SkMax32(maxCols[x], lod.width());
219 maxRows[y] = SkMax32(maxRows[y], lod.height());
220 }
221 }
222 // Draw the patches by generating their mesh with the maximum level of detai l per axis.
223 for (int y = 0; y < fRows; y++) {
224 for (int x = 0; x < fCols; x++) {
225 SkPatch patch;
226 this->getPatchAt(x, y, &patch);
227 SkPatch::VertexData data;
228 patch.getVertexData(&data, maxCols[x], maxRows[y]);
229 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCo unt,
230 data.fPoints, data.fTexCoords, data.fColors, NU LL,
231 data.fIndices, data.fIndexCount, paint);
232 }
233 }
234 SkDELETE_ARRAY(maxCols);
235 SkDELETE_ARRAY(maxRows);
236 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698