1 7 8 package java.awt.geom; 9 10 import java.util.*; 11 12 21 public class FlatteningPathIterator implements PathIterator { 22 static final int GROW_SIZE = 24; 24 PathIterator src; 26 double squareflat; 29 int limit; 31 double hold[] = new double[14]; 41 double curx, cury; 43 double movx, movy; 45 int holdType; 48 int holdEnd; 51 int holdIndex; 57 int levels[]; 61 int levelIndex; 65 boolean done; 67 77 public FlatteningPathIterator(PathIterator src, double flatness) { 78 this(src, flatness, 10); 79 } 80 81 99 public FlatteningPathIterator(PathIterator src, double flatness, 100 int limit) { 101 if (flatness < 0.0) { 102 throw new IllegalArgumentException ("flatness must be >= 0"); 103 } 104 if (limit < 0) { 105 throw new IllegalArgumentException ("limit must be >= 0"); 106 } 107 this.src = src; 108 this.squareflat = flatness * flatness; 109 this.limit = limit; 110 this.levels = new int[limit + 1]; 111 next(false); 113 } 114 115 119 public double getFlatness() { 120 return Math.sqrt(squareflat); 121 } 122 123 128 public int getRecursionLimit() { 129 return limit; 130 } 131 132 140 public int getWindingRule() { 141 return src.getWindingRule(); 142 } 143 144 149 public boolean isDone() { 150 return done; 151 } 152 153 157 void ensureHoldCapacity(int want) { 158 if (holdIndex - want < 0) { 159 int have = hold.length - holdIndex; 160 int newsize = hold.length + GROW_SIZE; 161 double newhold[] = new double[newsize]; 162 System.arraycopy(hold, holdIndex, 163 newhold, holdIndex + GROW_SIZE, 164 have); 165 hold = newhold; 166 holdIndex += GROW_SIZE; 167 holdEnd += GROW_SIZE; 168 } 169 } 170 171 176 public void next() { 177 next(true); 178 } 179 180 private void next(boolean doNext) { 181 int level; 182 183 if (holdIndex >= holdEnd) { 184 if (doNext) { 185 src.next(); 186 } 187 if (src.isDone()) { 188 done = true; 189 return; 190 } 191 holdType = src.currentSegment(hold); 192 levelIndex = 0; 193 levels[0] = 0; 194 } 195 196 switch (holdType) { 197 case SEG_MOVETO: 198 case SEG_LINETO: 199 curx = hold[0]; 200 cury = hold[1]; 201 if (holdType == SEG_MOVETO) { 202 movx = curx; 203 movy = cury; 204 } 205 holdIndex = 0; 206 holdEnd = 0; 207 break; 208 case SEG_CLOSE: 209 curx = movx; 210 cury = movy; 211 holdIndex = 0; 212 holdEnd = 0; 213 break; 214 case SEG_QUADTO: 215 if (holdIndex >= holdEnd) { 216 holdIndex = hold.length - 6; 218 holdEnd = hold.length - 2; 219 hold[holdIndex + 0] = curx; 220 hold[holdIndex + 1] = cury; 221 hold[holdIndex + 2] = hold[0]; 222 hold[holdIndex + 3] = hold[1]; 223 hold[holdIndex + 4] = curx = hold[2]; 224 hold[holdIndex + 5] = cury = hold[3]; 225 } 226 227 level = levels[levelIndex]; 228 while (level < limit) { 229 if (QuadCurve2D.getFlatnessSq(hold, holdIndex) < squareflat) { 230 break; 231 } 232 233 ensureHoldCapacity(4); 234 QuadCurve2D.subdivide(hold, holdIndex, 235 hold, holdIndex - 4, 236 hold, holdIndex); 237 holdIndex -= 4; 238 239 level++; 246 levels[levelIndex] = level; 247 levelIndex++; 248 levels[levelIndex] = level; 249 } 250 251 holdIndex += 4; 257 levelIndex--; 258 break; 259 case SEG_CUBICTO: 260 if (holdIndex >= holdEnd) { 261 holdIndex = hold.length - 8; 263 holdEnd = hold.length - 2; 264 hold[holdIndex + 0] = curx; 265 hold[holdIndex + 1] = cury; 266 hold[holdIndex + 2] = hold[0]; 267 hold[holdIndex + 3] = hold[1]; 268 hold[holdIndex + 4] = hold[2]; 269 hold[holdIndex + 5] = hold[3]; 270 hold[holdIndex + 6] = curx = hold[4]; 271 hold[holdIndex + 7] = cury = hold[5]; 272 } 273 274 level = levels[levelIndex]; 275 while (level < limit) { 276 if (CubicCurve2D.getFlatnessSq(hold, holdIndex) < squareflat) { 277 break; 278 } 279 280 ensureHoldCapacity(6); 281 CubicCurve2D.subdivide(hold, holdIndex, 282 hold, holdIndex - 6, 283 hold, holdIndex); 284 holdIndex -= 6; 285 286 level++; 293 levels[levelIndex] = level; 294 levelIndex++; 295 levels[levelIndex] = level; 296 } 297 298 holdIndex += 6; 304 levelIndex--; 305 break; 306 } 307 } 308 309 329 public int currentSegment(float[] coords) { 330 if (isDone()) { 331 throw new NoSuchElementException("flattening iterator out of bounds"); 332 } 333 int type = holdType; 334 if (type != SEG_CLOSE) { 335 coords[0] = (float) hold[holdIndex + 0]; 336 coords[1] = (float) hold[holdIndex + 1]; 337 if (type != SEG_MOVETO) { 338 type = SEG_LINETO; 339 } 340 } 341 return type; 342 } 343 344 364 public int currentSegment(double[] coords) { 365 if (isDone()) { 366 throw new NoSuchElementException("flattening iterator out of bounds"); 367 } 368 int type = holdType; 369 if (type != SEG_CLOSE) { 370 coords[0] = hold[holdIndex + 0]; 371 coords[1] = hold[holdIndex + 1]; 372 if (type != SEG_MOVETO) { 373 type = SEG_LINETO; 374 } 375 } 376 return type; 377 } 378 } 379 | Popular Tags |