1 package org.antlr.xjlib.appkit.swing; 2 3 import java.awt.*; 4 import java.awt.font.FontRenderContext ; 5 import java.awt.font.GlyphVector ; 6 import java.awt.font.TextAttribute ; 7 import java.awt.font.TextLayout ; 8 import java.awt.geom.*; 9 import java.awt.image.*; 10 import java.awt.image.renderable.RenderableImage ; 11 import java.text.AttributedCharacterIterator ; 12 import java.text.AttributedString ; 13 import java.text.DecimalFormat ; 14 import java.text.DecimalFormatSymbols ; 15 import java.util.Map ; 16 47 48 public class XJGraphics2DPS extends Graphics2D { 49 50 protected static final String NEWLINE = System.getProperty("line.separator"); 51 52 protected StringBuffer ps; 53 protected Font font; 54 protected Color color; 55 protected Color background; 56 protected Stroke stroke; 57 protected AffineTransform transform; 58 protected FontRenderContext fontRenderContext; 59 protected Point upperLeftCorner; 60 protected Point lowerRightCorner; 61 62 protected DecimalFormat df; 63 64 protected int marginWidth, marginHeight; 65 66 public XJGraphics2DPS() { 67 ps = new StringBuffer (); 68 upperLeftCorner = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); 69 lowerRightCorner = new Point(); 70 transform = new AffineTransform(); 71 fontRenderContext = new FontRenderContext (null, false, true); 72 73 DecimalFormatSymbols s = new DecimalFormatSymbols (); 74 s.setDecimalSeparator('.'); 75 df = new DecimalFormat ("###.##", s); 76 77 setFont(null); 78 setStroke(new BasicStroke()); 79 setMargins(0, 0); 80 } 81 82 public void setMargins(int width, int height) { 83 marginWidth = width; 84 marginHeight = height; 85 } 86 87 public String redefineOperator(String op, String operator) { 88 return "/"+op+" { "+operator+" } bind def"+NEWLINE; 89 } 90 91 public String getPSText() { 92 lowerRightCorner.x += marginWidth; 94 lowerRightCorner.y += marginHeight; 95 upperLeftCorner.x -= marginWidth; 96 upperLeftCorner.y -= marginHeight; 97 98 StringBuffer eps = new StringBuffer (); 100 101 eps.append("%!PS-Adobe-3.0 EPSF-3.0"); 102 eps.append(NEWLINE); 103 eps.append("%%Creator: XJGraphics2DPS (c) 2005 by Jean Bovet and Terence Parr"); 104 eps.append(NEWLINE); 105 106 eps.append("%%BoundingBox: 0 0 "); 107 eps.append(lowerRightCorner.x - upperLeftCorner.x); 108 eps.append(" "); 109 eps.append(lowerRightCorner.y - upperLeftCorner.y); 110 eps.append(NEWLINE); 111 112 eps.append("%%Origin: 0 0"); 113 eps.append(NEWLINE); 114 eps.append("%%Pages: 1"); 115 eps.append(NEWLINE); 116 eps.append("%%Page: 1 1"); 117 eps.append(NEWLINE); 118 eps.append("%%EndComments"); 119 eps.append(NEWLINE); 120 121 eps.append(redefineOperator("tr", "translate")); 123 eps.append(redefineOperator("sc", "scale")); 124 eps.append(redefineOperator("gs", "gsave")); 125 eps.append(redefineOperator("gr", "grestore")); 126 eps.append(redefineOperator("m", "moveto")); 127 eps.append(redefineOperator("l", "lineto")); 128 eps.append(redefineOperator("c", "curveto")); 129 eps.append(redefineOperator("f", "fill")); 130 eps.append(redefineOperator("s", "stroke")); 131 eps.append(redefineOperator("cp", "closepath")); 132 eps.append(redefineOperator("rgb", "setrgbcolor")); 133 eps.append(redefineOperator("sw", "setlinewidth")); 134 eps.append(redefineOperator("sm", "setmiterlimit")); 135 eps.append(redefineOperator("sj", "setlinejoin")); 136 eps.append(redefineOperator("slc", "setlinecap")); 137 eps.append(redefineOperator("sd", "setdash")); 138 139 eps.append(-upperLeftCorner.x); 141 eps.append(" "); 142 eps.append(upperLeftCorner.y + (lowerRightCorner.y-upperLeftCorner.y)); 143 eps.append(" tr"); 144 eps.append(NEWLINE); 145 146 eps.append(ps); 148 149 return eps.toString(); 150 } 151 152 public void psAppend(double v) { 153 psAppend(df.format(v)); 154 } 155 156 public void psAppend(String s) { 157 if(ps.length() > 0) { 158 char c = ps.charAt(ps.length()-1); 159 if(c != ' ' && !String.valueOf(c).equals(NEWLINE)) 160 ps.append(' '); 161 } 162 ps.append(s); 163 } 164 165 public void psGSave() { 166 psAppend("gs"); 167 psAppend(NEWLINE); 168 } 169 170 public void psGRestore() { 171 psAppend("gr"); 172 psAppend(NEWLINE); 173 } 174 175 public void psMoveTo(double x, double y) { 176 psAppend(x); 177 psAppend(y); 178 psAppend("m"); 179 psAppend(NEWLINE); 180 } 181 182 public void psLineTo(double x, double y) { 183 psAppend(x); 184 psAppend(y); 185 psAppend("l"); 186 psAppend(NEWLINE); 187 } 188 189 public void psCurveTo(double x0, double y0, double x1, double y1, double x2, double y2) { 190 psAppend(x0); 191 psAppend(y0); 192 psAppend(x1); 193 psAppend(y1); 194 psAppend(x2); 195 psAppend(y2); 196 psAppend("c"); 197 psAppend(NEWLINE); 198 } 199 200 public void psTranslate(double x, double y) { 201 psAppend(x); 202 psAppend(y); 203 psAppend("tr"); 204 psAppend(NEWLINE); 205 } 206 207 public void psScale(double x, double y) { 208 psAppend(x); 209 psAppend(y); 210 psAppend("sc"); 211 psAppend(NEWLINE); 212 } 213 214 public void psFill() { 215 psAppend("f"); 216 psAppend(NEWLINE); 217 } 218 219 public void psStroke() { 220 psAppend("s"); 221 psAppend(NEWLINE); 222 } 223 224 public void psClosePath() { 225 psAppend("cp"); 226 psAppend(NEWLINE); 227 } 228 229 public void psDrawShape(Shape s, boolean fill) { 230 double coord[] = new double[6]; 231 double x0, y0, x1, y1, x2, y2; 232 double cpx = 0, cpy = 0; 234 s = transform.createTransformedShape(s); 236 237 Rectangle2D r = s.getBounds2D(); 239 upperLeftCorner.x = (int) Math.min(upperLeftCorner.x, r.getMinX()); 240 upperLeftCorner.y = (int) Math.min(upperLeftCorner.y, r.getMinY()); 241 lowerRightCorner.x = (int) Math.max(lowerRightCorner.x, r.getMaxX()); 242 lowerRightCorner.y = (int) Math.max(lowerRightCorner.y, r.getMaxY()); 243 244 PathIterator iter = s.getPathIterator(null); 246 while(!iter.isDone()) { 247 int seg = iter.currentSegment(coord); 248 x0 = coord[0]; 249 y0 = -coord[1]; 250 x1 = coord[2]; 251 y1 = -coord[3]; 252 x2 = coord[4]; 253 y2 = -coord[5]; 254 255 switch(seg) { 256 case PathIterator.SEG_MOVETO: 257 psMoveTo(x0, y0); 258 cpx = x0; cpy = y0; 259 break; 260 261 case PathIterator.SEG_LINETO: 262 psLineTo(x0, y0); 263 cpx = x0; cpy = y0; 264 break; 265 266 case PathIterator.SEG_CUBICTO: 267 psCurveTo(x0, y0, x1, y1, x2, y2); 268 cpx = x2; cpy = y2; 269 break; 270 271 case PathIterator.SEG_QUADTO: 272 psCurveTo( cpx+2/3.0*(x0-cpx), cpy+2/3.0*(y0-cpy), 273 x0+1/3.0*(x1-x0), y0+1/3.0*(y1-y0), 274 x1, y1); 275 cpx = x1; cpy = y1; 276 break; 277 278 case PathIterator.SEG_CLOSE: 279 psClosePath(); 280 break; 281 } 282 iter.next(); 283 } 284 if(fill) 285 psFill(); 286 else 287 psStroke(); 288 } 289 290 public String arrayToString(float[] array) { 291 StringBuffer sb = new StringBuffer (); 292 if(array != null) { 293 for(int index=0; index<array.length; index++) { 294 sb.append(array[index]); 295 if(index < array.length-1) 296 sb.append(" "); 297 } 298 } 299 return sb.toString(); 300 } 301 302 public void draw(Shape s) { 303 psDrawShape(s, false); 304 } 305 306 public void fill(Shape s) { 307 psDrawShape(s, true); 308 } 309 310 public void drawString(String str, int x, int y) { 311 drawString(str, (float)x, (float)y); 312 } 313 314 public void drawString(String s, float x, float y) { 315 if(s == null || s.length() == 0) 316 return; 317 318 AttributedString as = new AttributedString (s); 319 as.addAttribute(TextAttribute.FONT, getFont()); 320 drawString(as.getIterator(), x, y); 321 } 322 323 public void drawString(AttributedCharacterIterator iterator, int x, int y) { 324 drawString(iterator, (float)x, (float)y); 325 } 326 327 public void drawString(AttributedCharacterIterator iterator, float x, float y) { 328 TextLayout layout = new TextLayout (iterator, getFontRenderContext()); 329 Shape shape = layout.getOutline(AffineTransform.getTranslateInstance(x, y)); 330 fill(shape); 331 } 332 333 public void drawChars(char data[], int offset, int length, int x, int y) { 334 drawString(new String (data, offset, length), x, y); 335 } 336 337 public void drawBytes(byte data[], int offset, int length, int x, int y) { 338 drawString(new String (data, 0, offset, length), x, y); 339 } 340 341 public void drawGlyphVector(GlyphVector g, float x, float y) { 342 fill(g.getOutline(x, y)); 343 } 344 345 public Graphics create() { 346 return new XJGraphics2DPS(); 347 } 348 349 public void translate(int x, int y) { 350 translate((double)x, (double)y); 351 } 352 353 public void translate(double tx, double ty) { 354 transform(AffineTransform.getTranslateInstance(tx, ty)); 355 } 356 357 public void rotate(double theta) { 358 transform(AffineTransform.getRotateInstance(theta)); 359 } 360 361 public void rotate(double theta, double x, double y) { 362 transform(AffineTransform.getRotateInstance(theta, x, y)); 363 } 364 365 public void scale(double sx, double sy) { 366 transform(AffineTransform.getScaleInstance(sx, sy)); 367 } 368 369 public void shear(double shx, double shy) { 370 transform(AffineTransform.getShearInstance(shx, shy)); 371 } 372 373 public void transform(AffineTransform Tx) { 374 transform.concatenate(Tx); 375 } 376 377 public void setTransform(AffineTransform Tx) { 378 if(Tx == null) 379 transform = new AffineTransform(); 380 else 381 transform = Tx; 382 } 383 384 public AffineTransform getTransform() { 385 return transform; 386 } 387 388 public Font getFont() { 389 return font; 390 } 391 392 public void setFont(Font font) { 393 this.font = font==null?Font.decode(null):font; 394 } 397 398 public Color getColor() { 399 return color; 400 } 401 402 public void setColor(Color c) { 403 this.color = c; 404 psAppend(c.getRed()/255.0); 405 psAppend(c.getGreen()/255.0); 406 psAppend(c.getBlue()/255.0); 407 psAppend("rgb"); 408 psAppend(NEWLINE); 409 } 410 411 public void setBackground(Color color) { 412 background = color; 413 } 414 415 public Color getBackground() { 416 return background; 417 } 418 419 public void setStroke(Stroke s) { 420 this.stroke = s; 421 if(s instanceof BasicStroke) { 422 BasicStroke bs = (BasicStroke)s; 423 psAppend(bs.getLineWidth()+" sw"+NEWLINE); 424 psAppend(Math.max(1, bs.getMiterLimit())+" sm"+NEWLINE); 425 psAppend(bs.getLineJoin()+" sj"+NEWLINE); 426 psAppend(bs.getEndCap()+" slc"+NEWLINE); 427 psAppend("["+arrayToString(bs.getDashArray())+"] "+bs.getDashPhase()+" sd"+NEWLINE); 428 } 429 } 430 431 public Stroke getStroke() { 432 return stroke; 433 } 434 435 public FontRenderContext getFontRenderContext() { 436 return fontRenderContext; 437 } 438 439 public FontMetrics getFontMetrics() { 440 return getFontMetrics(getFont()); 441 } 442 443 public FontMetrics getFontMetrics(Font f) { 444 BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); 445 Graphics g = image.getGraphics(); 446 return g.getFontMetrics(f); 447 } 448 449 public void drawLine(int x1, int y1, int x2, int y2) { 450 draw(new Line2D.Float(x1, y1, x2, y2)); 451 } 452 453 public void drawRect(int x, int y, int width, int height) { 454 draw(new Rectangle(x, y, width, height)); 455 } 456 457 public void fillRect(int x, int y, int width, int height) { 458 fill(new Rectangle(x, y, width, height)); 459 } 460 461 public void clearRect(int x, int y, int width, int height) { 462 Color oldColor = getColor(); 463 setColor(background); 464 fillRect(x, y, width, height); 465 setColor(oldColor); 466 } 467 468 public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { 469 draw(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight)); 470 } 471 472 public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { 473 fill(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight)); 474 } 475 476 public void drawOval(int x, int y, int width, int height) { 477 draw(new Ellipse2D.Float(x, y, width, height)); 478 } 479 480 public void fillOval(int x, int y, int width, int height) { 481 fill(new Ellipse2D.Float(x, y, width, height)); 482 } 483 484 public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { 485 draw(new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN)); 486 } 487 488 public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { 489 fill(new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE)); 490 } 491 492 public void drawPolyline(int xPoints[], int yPoints[], int nPoints) { 493 if(nPoints == 0) 494 return; 495 496 GeneralPath path = new GeneralPath(); 497 path.moveTo(xPoints[0], yPoints[0]); 498 for(int p=1; p<nPoints; p++) 499 path.lineTo(xPoints[p], yPoints[p]); 500 draw(path); 501 } 502 503 public void drawPolygon(int xPoints[], int yPoints[], int nPoints) { 504 draw(new Polygon(xPoints, yPoints, nPoints)); 505 } 506 507 public void drawPolygon(Polygon p) { 508 draw(p); 509 } 510 511 public void fillPolygon(int xPoints[], int yPoints[], int nPoints) { 512 fill(new Polygon(xPoints, yPoints, nPoints)); 513 } 514 515 public boolean drawImage(Image img, int x, int y, ImageObserver observer) { 516 return drawImage(img, x, y, Color.white, observer); 517 } 518 519 public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { 520 return drawImage(img, x, y, width, height, Color.white, observer); 521 } 522 523 public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { 524 return drawImage(img, x, y, img.getWidth(null), img.getHeight(null), bgcolor, observer); 525 } 526 527 public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { 528 return drawImage(img, x, y, x+width, y+height, 0, 0, width, height, bgcolor, observer); 529 } 530 531 public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { 532 return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, Color.white, observer); 533 } 534 535 public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { 536 int width = dx2-dx1; 537 int height = dy2-dy1; 538 539 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 540 Graphics g = image.getGraphics(); 541 g.drawImage(img, 0, 0, width, height, sx1, sy1, sx2, sy2, bgcolor, observer); 542 543 psGSave(); 544 psTranslate(dx1, -(dy1+height)); 545 psAppend("/picstr "+width *ComponentsPerPixel +" string def"+NEWLINE); 546 psScale(width, height); 547 psAppend("/displayimage {"+NEWLINE); 548 psAppend(width +" "+height +" "+BitsPerComponent+" ["+width +" 0 0 -"+height +" 0 "+height +"]"+NEWLINE); 549 psAppend("{currentfile picstr readhexstring pop} false "+ComponentsPerPixel+" colorimage} def"+NEWLINE); 550 psAppend("displayimage"+NEWLINE); 551 552 boolean success = true; 553 try { 554 getPixels(img, 0, 0, width, height); 555 } catch (Exception e) { 556 System.err.println("XJGraphics2DPS: draw image error ("+e+")"); 557 success = false; 558 } 559 560 psGRestore(); 561 562 return success; 563 } 564 565 569 protected static final int BytesPerComponent = 1; 570 protected static final int BitsPerComponent = BytesPerComponent * 8; 571 protected static final int ComponentsPerPixel = 3; 572 protected static char[] hexmap = { '0','1','2','3','4', 573 '5','6','7','8','9', 574 'A','B','C','D','E','F'}; 575 576 579 public void getPixels(Image img, int x, int y, int w, int h) 580 throws Exception { 581 int[] pixels = new int[w * h]; 582 PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w); 583 pg.grabPixels(); 584 if ((pg.getStatus() & ImageObserver.ABORT) != 0) { 585 throw new Exception ("image fetch aborted or errored"); 586 } 587 for (int j = 0; j < h; j++) { 588 for (int i = 0; i < w; i++) { 589 getSinglePixel(x+i, y+j, pixels[j * w + i]); 590 } 591 ps.append(NEWLINE); 592 } 593 } 594 595 598 public void getSinglePixel(int x, int y, int pixel) { 599 int red = (pixel >> 16) & 0xFF; 601 int green = (pixel >> 8) & 0xFF; 602 int blue = (pixel ) & 0xFF; 603 char[] hexValue = new char[2]; 604 ASCIIHexEncode(red, hexValue); ps.append(hexValue); 605 ASCIIHexEncode(green, hexValue); ps.append(hexValue); 606 ASCIIHexEncode(blue, hexValue); ps.append(hexValue); 607 } 608 609 612 public static void ASCIIHexEncode(int b, char[] c) { 613 c[0]=hexmap[b>>4]; c[1]=hexmap[b&0xF]; } 616 617 619 620 621 public void dispose() { 622 } 623 624 public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { 625 return false; 626 } 627 628 public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { 629 } 630 631 public void drawRenderedImage(RenderedImage img, AffineTransform xform) { 632 } 633 634 public void drawRenderableImage(RenderableImage img, AffineTransform xform) { 635 } 636 637 public boolean hit(Rectangle rect, Shape s, boolean onStroke) { 638 return false; 639 } 640 641 public GraphicsConfiguration getDeviceConfiguration() { 642 return null; 643 } 644 645 public void setComposite(Composite comp) { 646 } 647 648 public void setPaint(Paint paint) { 649 } 650 651 public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { 652 } 653 654 public Object getRenderingHint(RenderingHints.Key hintKey) { 655 return null; 656 } 657 658 public void setRenderingHints(Map hints) { 659 } 660 661 public void addRenderingHints(Map hints) { 662 } 663 664 public RenderingHints getRenderingHints() { 665 return null; 666 } 667 668 public void setPaintMode() { 669 } 670 671 public void setXORMode(Color c1) { 672 } 673 674 public Rectangle getClipBounds() { 675 return null; 676 } 677 678 public void clipRect(int x, int y, int width, int height) { 679 } 680 681 public void setClip(int x, int y, int width, int height) { 682 } 683 684 public Shape getClip() { 685 return null; 686 } 687 688 public void setClip(Shape clip) { 689 } 690 691 public void copyArea(int x, int y, int width, int height, int dx, int dy) { 692 } 693 694 public Paint getPaint() { 695 return null; 696 } 697 698 public Composite getComposite() { 699 return null; 700 } 701 702 public void clip(Shape s) { 703 } 704 705 } 706 | Popular Tags |