1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.svg.edu.client.maze;
19
20 import org.vectomatic.dom.svg.OMSVGDocument;
21 import org.vectomatic.dom.svg.OMSVGGElement;
22 import org.vectomatic.dom.svg.OMSVGPathElement;
23 import org.vectomatic.dom.svg.OMSVGPathSeg;
24 import org.vectomatic.dom.svg.OMSVGPathSegCurvetoCubicAbs;
25 import org.vectomatic.dom.svg.OMSVGPathSegCurvetoCubicRel;
26 import org.vectomatic.dom.svg.OMSVGPathSegCurvetoCubicSmoothAbs;
27 import org.vectomatic.dom.svg.OMSVGPathSegCurvetoCubicSmoothRel;
28 import org.vectomatic.dom.svg.OMSVGPathSegLinetoAbs;
29 import org.vectomatic.dom.svg.OMSVGPathSegLinetoHorizontalAbs;
30 import org.vectomatic.dom.svg.OMSVGPathSegLinetoHorizontalRel;
31 import org.vectomatic.dom.svg.OMSVGPathSegLinetoRel;
32 import org.vectomatic.dom.svg.OMSVGPathSegLinetoVerticalAbs;
33 import org.vectomatic.dom.svg.OMSVGPathSegLinetoVerticalRel;
34 import org.vectomatic.dom.svg.OMSVGPathSegList;
35 import org.vectomatic.dom.svg.OMSVGPathSegMovetoAbs;
36 import org.vectomatic.dom.svg.OMSVGPathSegMovetoRel;
37 import org.vectomatic.dom.svg.OMSVGRect;
38 import org.vectomatic.dom.svg.OMSVGRectElement;
39 import org.vectomatic.svg.edu.client.maze.RectangularMaze.RectangularCell;
40
41 import com.google.gwt.core.client.GWT;
42
43
44
45
46
47 public class Rasterizer {
48 static class RasterizationResult {
49 RectangularCell[][] grid;
50 int srcX, srcY;
51 int destX, destY;
52 public RasterizationResult(int colCount, int rowCount) {
53 grid = new RectangularCell[colCount][rowCount];
54 for (int i = 0; i < colCount; i++) {
55 grid[i] = new RectangularCell[rowCount];
56 }
57 }
58 }
59
60 public static RasterizationResult rasterize(OMSVGPathElement path, OMSVGGElement cellGroup, int colCount, int rowCount) {
61 long t1 = System.currentTimeMillis();
62 OMSVGRect bbox = path.getBBox();
63 float minx = bbox.getX();
64 float miny = bbox.getY();
65 float width = bbox.getWidth();
66 float height = bbox.getHeight();
67 Canvas canvas = Canvas.createCanvas((int)width, (int)height);
68
69
70 OMSVGPathSegList segs = path.getPathSegList();
71 canvas.beginPath();
72 float x = 0f, y = 0f, prevx2 = 0, prevy2 = 0, x1, y1;
73 boolean prevIsCubic = false;
74 for (int i = 0, size = segs.getNumberOfItems(); i < size; i++) {
75 OMSVGPathSeg seg = segs.getItem(i);
76 switch (seg.getPathSegType()) {
77 case OMSVGPathSeg.PATHSEG_CLOSEPATH:
78 canvas.closePath();
79 prevIsCubic = false;
80 break;
81 case OMSVGPathSeg.PATHSEG_MOVETO_ABS:
82 OMSVGPathSegMovetoAbs moveToAbs = (OMSVGPathSegMovetoAbs)seg;
83 prevx2 = x = moveToAbs.getX();
84 prevy2 = y = moveToAbs.getY();
85 canvas.moveTo(x, y);
86 prevIsCubic = false;
87 break;
88 case OMSVGPathSeg.PATHSEG_MOVETO_REL:
89 OMSVGPathSegMovetoRel moveToRel = (OMSVGPathSegMovetoRel)seg;
90 x += moveToRel.getX();
91 y += moveToRel.getY();
92 prevx2 = x;
93 prevy2 = y;
94 canvas.moveTo(x, y);
95 prevIsCubic = false;
96 break;
97 case OMSVGPathSeg.PATHSEG_LINETO_ABS:
98 OMSVGPathSegLinetoAbs lineToAbs = (OMSVGPathSegLinetoAbs)seg;
99 prevx2 = x = lineToAbs.getX();
100 prevy2 = y = lineToAbs.getY();
101 canvas.lineTo(x, y);
102 prevIsCubic = false;
103 break;
104 case OMSVGPathSeg.PATHSEG_LINETO_REL:
105 OMSVGPathSegLinetoRel lineToRel = (OMSVGPathSegLinetoRel)seg;
106 x += lineToRel.getX();
107 y += lineToRel.getY();
108 prevx2 = x;
109 prevy2 = y;
110 canvas.lineTo(x, y);
111 prevIsCubic = false;
112 break;
113 case OMSVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
114 OMSVGPathSegCurvetoCubicAbs curveToCubicAbs = (OMSVGPathSegCurvetoCubicAbs)seg;
115 x = curveToCubicAbs.getX();
116 y = curveToCubicAbs.getY();
117 prevx2 = curveToCubicAbs.getX2();
118 prevy2 = curveToCubicAbs.getY2();
119 canvas.bezierCurveTo(curveToCubicAbs.getX1(), curveToCubicAbs.getY1(), prevx2, prevy2, x, y);
120 prevIsCubic = true;
121 break;
122 case OMSVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
123 OMSVGPathSegCurvetoCubicRel curveToCubicRel = (OMSVGPathSegCurvetoCubicRel)seg;
124 prevx2 = (curveToCubicRel.getX2() + x);
125 prevy2 = (curveToCubicRel.getY2() + y);
126 canvas.bezierCurveTo(curveToCubicRel.getX1() + x, curveToCubicRel.getY1() + y, prevx2, prevy2, curveToCubicRel.getX() + x, curveToCubicRel.getY() + y);
127 x += curveToCubicRel.getX();
128 y += curveToCubicRel.getY();
129 prevIsCubic = true;
130 break;
131 case OMSVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
132 OMSVGPathSegCurvetoCubicSmoothAbs curveToSmoothAbs = (OMSVGPathSegCurvetoCubicSmoothAbs)seg;
133 if (prevIsCubic) {
134 x1 = 2 * x - prevx2;
135 y1 = 2 * y - prevy2;
136 } else {
137 x1 = x;
138 y1 = y;
139 }
140 x = curveToSmoothAbs.getX();
141 y = curveToSmoothAbs.getY();
142 prevx2 = curveToSmoothAbs.getX2();
143 prevy2 = curveToSmoothAbs.getY2();
144 canvas.bezierCurveTo(x1, y1, prevx2, prevy2, x, y);
145 prevIsCubic = true;
146 break;
147 case OMSVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
148 OMSVGPathSegCurvetoCubicSmoothRel curveToSmoothRel = (OMSVGPathSegCurvetoCubicSmoothRel)seg;
149 if (prevIsCubic) {
150 x1 = 2 * x - prevx2;
151 y1 = 2 * y - prevy2;
152 } else {
153 x1 = x;
154 y1 = y;
155 }
156 prevx2 = (x + curveToSmoothRel.getX2());
157 prevy2 = (y + curveToSmoothRel.getY2());
158 x += curveToSmoothRel.getX();
159 y += curveToSmoothRel.getY();
160 canvas.bezierCurveTo(x1, y1, prevx2, prevy2, x, y);
161 prevIsCubic = true;
162 break;
163 case OMSVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
164 OMSVGPathSegLinetoHorizontalAbs lineToHorizAbs = (OMSVGPathSegLinetoHorizontalAbs)seg;
165 prevx2 = x = lineToHorizAbs.getX();
166 canvas.lineTo(x, y);
167 prevIsCubic = false;
168 break;
169 case OMSVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
170 OMSVGPathSegLinetoHorizontalRel lineToHorizRel = (OMSVGPathSegLinetoHorizontalRel)seg;
171 x += lineToHorizRel.getX();
172 prevx2 = x;
173 canvas.lineTo(x, y);
174 prevIsCubic = false;
175 break;
176 case OMSVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
177 OMSVGPathSegLinetoVerticalAbs lineToVertAbs = (OMSVGPathSegLinetoVerticalAbs)seg;
178 prevy2 = y = lineToVertAbs.getY();
179 canvas.lineTo(x, y);
180 prevIsCubic = false;
181 break;
182 case OMSVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
183 OMSVGPathSegLinetoVerticalRel lineToVertRel = (OMSVGPathSegLinetoVerticalRel)seg;
184 y += lineToVertRel.getY();
185 prevy2 = y;
186 canvas.lineTo(x, y);
187 prevIsCubic = false;
188 break;
189 case OMSVGPathSeg.PATHSEG_ARC_ABS:
190 case OMSVGPathSeg.PATHSEG_ARC_REL:
191 default:
192 throw new IllegalStateException("Unsupported seg type:" + seg.getPathSegType());
193 }
194 }
195
196
197
198 String start = path.getAttributeNS(RectangularMaze.VECTOMATIC_NS, "start");
199 String[] startArray = start.split("x");
200 float xstart = Float.parseFloat(startArray[0]);
201 float ystart = Float.parseFloat(startArray[1]);
202 String end = path.getAttributeNS(RectangularMaze.VECTOMATIC_NS, "end");
203 String[] endArray = end.split("x");
204 float xend = Float.parseFloat(endArray[0]);
205 float yend = Float.parseFloat(endArray[1]);
206 float dstart = Float.MAX_VALUE, dend = Float.MAX_VALUE;
207
208
209
210
211 OMSVGDocument doc = (OMSVGDocument) cellGroup.getOwnerDocument();
212 RasterizationResult result = new RasterizationResult(colCount, rowCount);
213
214 float cellWidth = width / colCount;
215 float cellHeight = height / rowCount;
216 for (int i = 0; i < colCount; i++) {
217 for (int j = 0; j < rowCount; j++) {
218
219 float px = minx + (i + 0.5f) * cellWidth;
220 float py = miny + (j + 0.5f) * cellHeight;
221 if (canvas.isPointInPath(px, py)) {
222 RectangularCell cell = new RectangularCell(i, j);
223 OMSVGRectElement rect = doc.createSVGRectElement(minx + i * cellWidth, miny + j * cellHeight, cellWidth, cellHeight, 0f, 0f);
224 cell.setRect(rect);
225 cellGroup.appendChild(rect);
226 float d = (px - xstart) * (px - xstart) + (py - ystart) * (py - ystart);
227 if (d < dstart) {
228 dstart = d;
229 result.srcX = i;
230 result.srcY = j;
231 }
232 d = (px - xend) * (px - xend) + (py - yend) * (py - yend);
233 if (d < dend) {
234 dend = d;
235 result.destX = i;
236 result.destY = j;
237 }
238 result.grid[i][j] = cell;
239 }
240 }
241 }
242 long t2 = System.currentTimeMillis();
243
244 GWT.log("cells rasterization = " + (t2 - t1));
245 return result;
246 }
247 }