1 7 8 package java.awt; 9 10 import java.awt.geom.GeneralPath ; 11 import java.awt.geom.PathIterator ; 12 import sun.dc.path.FastPathProducer; 13 import sun.dc.path.PathConsumer; 14 import sun.dc.path.PathException; 15 import sun.dc.pr.PathStroker; 16 import sun.dc.pr.PathDasher; 17 import sun.dc.pr.Rasterizer; 18 19 102 public class BasicStroke implements Stroke { 103 104 108 public final static int JOIN_MITER = 0; 109 110 114 public final static int JOIN_ROUND = 1; 115 116 120 public final static int JOIN_BEVEL = 2; 121 122 126 public final static int CAP_BUTT = 0; 127 128 133 public final static int CAP_ROUND = 1; 134 135 140 public final static int CAP_SQUARE = 2; 141 142 float width; 143 144 int join; 145 int cap; 146 float miterlimit; 147 148 float dash[]; 149 float dash_phase; 150 151 178 public BasicStroke(float width, int cap, int join, float miterlimit, 179 float dash[], float dash_phase) { 180 if (width < 0.0f) { 181 throw new IllegalArgumentException ("negative width"); 182 } 183 if (cap != CAP_BUTT && cap != CAP_ROUND && cap != CAP_SQUARE) { 184 throw new IllegalArgumentException ("illegal end cap value"); 185 } 186 if (join == JOIN_MITER) { 187 if (miterlimit < 1.0f) { 188 throw new IllegalArgumentException ("miter limit < 1"); 189 } 190 } else if (join != JOIN_ROUND && join != JOIN_BEVEL) { 191 throw new IllegalArgumentException ("illegal line join value"); 192 } 193 if (dash != null) { 194 if (dash_phase < 0.0f) { 195 throw new IllegalArgumentException ("negative dash phase"); 196 } 197 boolean allzero = true; 198 for (int i = 0; i < dash.length; i++) { 199 float d = dash[i]; 200 if (d > 0.0) { 201 allzero = false; 202 } else if (d < 0.0) { 203 throw new IllegalArgumentException ("negative dash length"); 204 } 205 } 206 if (allzero) { 207 throw new IllegalArgumentException ("dash lengths all zero"); 208 } 209 } 210 this.width = width; 211 this.cap = cap; 212 this.join = join; 213 this.miterlimit = miterlimit; 214 if (dash != null) { 215 this.dash = (float []) dash.clone(); 216 } 217 this.dash_phase = dash_phase; 218 } 219 220 235 public BasicStroke(float width, int cap, int join, float miterlimit) { 236 this(width, cap, join, miterlimit, null, 0.0f); 237 } 238 239 253 public BasicStroke(float width, int cap, int join) { 254 this(width, cap, join, 10.0f, null, 0.0f); 255 } 256 257 264 public BasicStroke(float width) { 265 this(width, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f); 266 } 267 268 274 public BasicStroke() { 275 this(1.0f, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f); 276 } 277 278 279 285 public Shape createStrokedShape(Shape s) { 286 FillAdapter filler = new FillAdapter(); 287 PathStroker stroker = new PathStroker(filler); 288 PathDasher dasher = null; 289 290 try { 291 PathConsumer consumer; 292 293 stroker.setPenDiameter(width); 294 stroker.setPenT4(null); 295 stroker.setCaps(RasterizerCaps[cap]); 296 stroker.setCorners(RasterizerCorners[join], miterlimit); 297 if (dash != null) { 298 dasher = new PathDasher(stroker); 299 dasher.setDash(dash, dash_phase); 300 dasher.setDashT4(null); 301 consumer = dasher; 302 } else { 303 consumer = stroker; 304 } 305 306 feedConsumer(consumer, s.getPathIterator(null)); 307 } finally { 308 stroker.dispose(); 309 if (dasher != null) { 310 dasher.dispose(); 311 } 312 } 313 314 return filler.getShape(); 315 } 316 317 private void feedConsumer(PathConsumer consumer, PathIterator pi) { 318 try { 319 consumer.beginPath(); 320 boolean pathClosed = false; 321 float mx = 0.0f; 322 float my = 0.0f; 323 float point[] = new float[6]; 324 325 while (!pi.isDone()) { 326 int type = pi.currentSegment(point); 327 if (pathClosed == true) { 328 pathClosed = false; 329 if (type != PathIterator.SEG_MOVETO) { 330 consumer.beginSubpath(mx, my); 332 } 333 } 334 switch (type) { 335 case PathIterator.SEG_MOVETO: 336 mx = point[0]; 337 my = point[1]; 338 consumer.beginSubpath(point[0], point[1]); 339 break; 340 case PathIterator.SEG_LINETO: 341 consumer.appendLine(point[0], point[1]); 342 break; 343 case PathIterator.SEG_QUADTO: 344 consumer.appendQuadratic(point[0], point[1], 346 point[2], point[3]); 347 break; 348 case PathIterator.SEG_CUBICTO: 349 consumer.appendCubic(point[0], point[1], 351 point[2], point[3], 352 point[4], point[5]); 353 break; 354 case PathIterator.SEG_CLOSE: 355 consumer.closedSubpath(); 356 pathClosed = true; 357 break; 358 } 359 pi.next(); 360 } 361 362 consumer.endPath(); 363 } catch (PathException e) { 364 throw new InternalError ("Unable to Stroke shape ("+ 365 e.getMessage()+")"); 366 } 367 } 368 369 377 public float getLineWidth() { 378 return width; 379 } 380 381 387 public int getEndCap() { 388 return cap; 389 } 390 391 397 public int getLineJoin() { 398 return join; 399 } 400 401 405 public float getMiterLimit() { 406 return miterlimit; 407 } 408 409 421 public float[] getDashArray() { 422 if (dash == null) { 423 return null; 424 } 425 426 return (float[]) dash.clone(); 427 } 428 429 437 public float getDashPhase() { 438 return dash_phase; 439 } 440 441 445 public int hashCode() { 446 int hash = Float.floatToIntBits(width); 447 hash = hash * 31 + join; 448 hash = hash * 31 + cap; 449 hash = hash * 31 + Float.floatToIntBits(miterlimit); 450 if (dash != null) { 451 hash = hash * 31 + Float.floatToIntBits(dash_phase); 452 for (int i = 0; i < dash.length; i++) { 453 hash = hash * 31 + Float.floatToIntBits(dash[i]); 454 } 455 } 456 return hash; 457 } 458 459 463 474 public boolean equals(Object obj) { 475 if (!(obj instanceof BasicStroke )) { 476 return false; 477 } 478 479 BasicStroke bs = (BasicStroke ) obj; 480 if (width != bs.width) { 481 return false; 482 } 483 484 if (join != bs.join) { 485 return false; 486 } 487 488 if (cap != bs.cap) { 489 return false; 490 } 491 492 if (miterlimit != bs.miterlimit) { 493 return false; 494 } 495 496 if (dash != null) { 497 if (dash_phase != bs.dash_phase) { 498 return false; 499 } 500 501 if (!java.util.Arrays.equals(dash, bs.dash)) { 502 return false; 503 } 504 } 505 else if (bs.dash != null) { 506 return false; 507 } 508 509 return true; 510 } 511 512 private static final int RasterizerCaps[] = { 513 Rasterizer.BUTT, Rasterizer.ROUND, Rasterizer.SQUARE 514 }; 515 516 private static final int RasterizerCorners[] = { 517 Rasterizer.MITER, Rasterizer.ROUND, Rasterizer.BEVEL 518 }; 519 520 private class FillAdapter implements PathConsumer { 521 boolean closed; 522 GeneralPath path; 523 524 public FillAdapter() { 525 path = new GeneralPath (GeneralPath.WIND_NON_ZERO); 526 } 527 528 public Shape getShape() { 529 return path; 530 } 531 532 public void dispose() { 533 } 534 535 public PathConsumer getConsumer() { 536 return null; 537 } 538 539 public void beginPath() {} 540 541 public void beginSubpath(float x0, float y0) { 542 if (closed) { 543 path.closePath(); 544 closed = false; 545 } 546 path.moveTo(x0, y0); 547 } 548 549 public void appendLine(float x1, float y1) { 550 path.lineTo(x1, y1); 551 } 552 553 public void appendQuadratic(float xm, float ym, float x1, float y1) { 554 path.quadTo(xm, ym, x1, y1); 555 } 556 557 public void appendCubic(float xm, float ym, 558 float xn, float yn, 559 float x1, float y1) { 560 path.curveTo(xm, ym, xn, yn, x1, y1); 561 } 562 563 public void closedSubpath() { 564 closed = true; 565 } 566 567 public void endPath() { 568 if (closed) { 569 path.closePath(); 570 closed = false; 571 } 572 } 573 574 public void useProxy(FastPathProducer proxy) 575 throws PathException 576 { 577 proxy.sendTo(this); 578 } 579 580 public long getCPathConsumer() { 581 return 0; 582 } 583 } 584 } 585 | Popular Tags |