1 17 18 19 20 package org.apache.fop.render.pcl; 21 22 import java.awt.BasicStroke ; 23 import java.awt.Color ; 24 import java.awt.Dimension ; 25 import java.awt.Graphics ; 26 import java.awt.Graphics2D ; 27 import java.awt.GraphicsConfiguration ; 28 import java.awt.GraphicsEnvironment ; 29 import java.awt.Image ; 30 import java.awt.Paint ; 31 import java.awt.Shape ; 32 import java.awt.Stroke ; 33 import java.awt.font.FontRenderContext ; 34 import java.awt.font.GlyphVector ; 35 import java.awt.geom.AffineTransform ; 36 import java.awt.geom.PathIterator ; 37 import java.awt.geom.Point2D ; 38 import java.awt.image.BufferedImage ; 39 import java.awt.image.ImageObserver ; 40 import java.awt.image.RenderedImage ; 41 import java.awt.image.renderable.RenderableImage ; 42 import java.io.IOException ; 43 import java.text.AttributedCharacterIterator ; 44 45 import org.apache.fop.util.UnitConv; 46 import org.apache.xmlgraphics.java2d.AbstractGraphics2D; 47 import org.apache.xmlgraphics.java2d.GraphicContext; 48 49 53 public class PCLGraphics2D extends AbstractGraphics2D { 54 55 56 protected PCLGenerator gen; 57 58 private boolean failOnUnsupportedFeature = true; 59 private boolean clippingDisabled = false; 60 61 65 public PCLGraphics2D(PCLGenerator gen) { 66 super(true); 67 this.gen = gen; 68 } 69 70 74 public PCLGraphics2D(PCLGraphics2D g) { 75 super(true); 76 this.gen = g.gen; 77 } 78 79 80 public Graphics create() { 81 PCLGraphics2D copy = new PCLGraphics2D(this); 82 copy.setGraphicContext((GraphicContext)getGraphicContext().clone()); 83 return copy; 84 } 85 86 87 public void dispose() { 88 this.gen = null; 89 } 90 91 95 public void setGraphicContext(GraphicContext c) { 96 this.gc = c; 97 } 98 99 103 public void setClippingDisabled(boolean value) { 104 this.clippingDisabled = value; 105 } 106 107 111 public void handleIOException(IOException ioe) { 112 ioe.printStackTrace(); 114 } 115 116 122 protected void handleUnsupportedFeature(String msg) { 123 if (this.failOnUnsupportedFeature) { 124 throw new UnsupportedOperationException (msg); 125 } 126 } 127 128 129 public GraphicsConfiguration getDeviceConfiguration() { 130 return GraphicsEnvironment.getLocalGraphicsEnvironment(). 131 getDefaultScreenDevice().getDefaultConfiguration(); 132 } 133 134 139 protected void applyStroke(Stroke stroke) throws IOException { 140 if (stroke instanceof BasicStroke ) { 141 BasicStroke bs = (BasicStroke )stroke; 142 143 float[] da = bs.getDashArray(); 144 if (da != null) { 145 146 gen.writeText("UL1,"); 147 int len = Math.min(20, da.length); 148 float patternLen = 0.0f; 149 for (int idx = 0; idx < len; idx++) { 150 patternLen += da[idx]; 151 } 152 if (len == 1) { 153 patternLen *= 2; 154 } 155 for (int idx = 0; idx < len; idx++) { 156 float perc = da[idx] * 100 / patternLen; 157 gen.writeText(gen.formatDouble2(perc)); 158 if (idx < da.length - 1) { 159 gen.writeText(","); 160 } 161 } 162 if (len == 1) { 163 gen.writeText("," + gen.formatDouble2(da[0] * 100 / patternLen )); 164 165 } 166 gen.writeText(";"); 167 171 Point2D ptLen = new Point2D.Double (patternLen, 0); 172 getTransform().deltaTransform(ptLen, ptLen); 174 double transLen = UnitConv.pt2mm(ptLen.distance(0, 0)); 175 gen.writeText("LT1," + gen.formatDouble4(transLen) + ",1;"); 176 } else { 177 gen.writeText("LT;"); 178 } 179 180 gen.writeText("LA1"); int ec = bs.getEndCap(); 182 switch (ec) { 183 case BasicStroke.CAP_BUTT: 184 gen.writeText(",1"); 185 break; 186 case BasicStroke.CAP_ROUND: 187 gen.writeText(",4"); 188 break; 189 case BasicStroke.CAP_SQUARE: 190 gen.writeText(",2"); 191 break; 192 default: System.err.println("Unsupported line cap: " + ec); 193 } 194 195 gen.writeText(",2"); int lj = bs.getLineJoin(); 197 switch (lj) { 198 case BasicStroke.JOIN_MITER: 199 gen.writeText(",1"); 200 break; 201 case BasicStroke.JOIN_ROUND: 202 gen.writeText(",4"); 203 break; 204 case BasicStroke.JOIN_BEVEL: 205 gen.writeText(",5"); 206 break; 207 default: System.err.println("Unsupported line join: " + lj); 208 } 209 210 float ml = bs.getMiterLimit(); 211 gen.writeText(",3" + gen.formatDouble4(ml)); 212 213 float lw = bs.getLineWidth(); 214 Point2D ptSrc = new Point2D.Double (lw, 0); 215 Point2D ptDest = getTransform().deltaTransform(ptSrc, null); 217 double transDist = UnitConv.pt2mm(ptDest.distance(0, 0)); 218 gen.writeText(";PW" + gen.formatDouble4(transDist) + ";"); 220 221 } else { 222 handleUnsupportedFeature("Unsupported Stroke: " + stroke.getClass().getName()); 223 } 224 } 225 226 231 protected void applyPaint(Paint paint) throws IOException { 232 if (paint instanceof Color ) { 233 Color col = (Color )paint; 234 int shade = gen.convertToPCLShade(col); 235 gen.writeText("TR0;FT10," + shade + ";"); 236 } else { 237 handleUnsupportedFeature("Unsupported Paint: " + paint.getClass().getName()); 238 } 239 } 240 241 private void writeClip(Shape imclip) throws IOException { 242 if (clippingDisabled) { 243 return; 244 } 245 if (imclip == null) { 246 } else { 248 handleUnsupportedFeature("Clipping is not supported. Shape: " + imclip); 249 262 } 263 } 264 265 266 public void draw(Shape s) { 267 try { 268 AffineTransform trans = getTransform(); 269 270 Shape imclip = getClip(); 271 writeClip(imclip); 272 273 if (!Color.black.equals(getColor())) { 274 handleUnsupportedFeature("Only black is supported as stroke color: " + getColor()); 276 } 277 applyStroke(getStroke()); 278 279 PathIterator iter = s.getPathIterator(trans); 280 processPathIteratorStroke(iter); 281 writeClip(null); 282 } catch (IOException ioe) { 283 handleIOException(ioe); 284 } 285 } 286 287 288 public void fill(Shape s) { 289 try { 290 AffineTransform trans = getTransform(); 291 Shape imclip = getClip(); 292 writeClip(imclip); 293 294 applyPaint(getPaint()); 295 296 PathIterator iter = s.getPathIterator(trans); 297 processPathIteratorFill(iter); 298 writeClip(null); 299 } catch (IOException ioe) { 300 handleIOException(ioe); 301 } 302 } 303 304 309 public void processPathIteratorStroke(PathIterator iter) throws IOException { 310 gen.writeText("\n"); 311 double[] vals = new double[6]; 312 boolean penDown = false; 313 double x = 0; 314 double y = 0; 315 StringBuffer sb = new StringBuffer (256); 316 penUp(sb); 317 while (!iter.isDone()) { 318 int type = iter.currentSegment(vals); 319 if (type == PathIterator.SEG_CLOSE) { 320 gen.writeText("PM;"); 321 gen.writeText(sb.toString()); 322 gen.writeText("PM2;EP;"); 323 sb.setLength(0); 324 iter.next(); 325 continue; 326 } else if (type == PathIterator.SEG_MOVETO) { 327 gen.writeText(sb.toString()); 328 sb.setLength(0); 329 if (penDown) { 330 penUp(sb); 331 penDown = false; 332 } 333 } else { 334 if (!penDown) { 335 penDown(sb); 336 penDown = true; 337 } 338 } 339 switch (type) { 340 case PathIterator.SEG_CLOSE: 341 break; 342 case PathIterator.SEG_MOVETO: 343 x = vals[0]; 344 y = vals[1]; 345 plotAbsolute(x, y, sb); 346 gen.writeText(sb.toString()); 347 sb.setLength(0); 348 break; 349 case PathIterator.SEG_LINETO: 350 x = vals[0]; 351 y = vals[1]; 352 plotAbsolute(x, y, sb); 353 break; 354 case PathIterator.SEG_CUBICTO: 355 x = vals[4]; 356 y = vals[5]; 357 bezierAbsolute(vals[0], vals[1], vals[2], vals[3], x, y, sb); 358 break; 359 case PathIterator.SEG_QUADTO: 360 double originX = x; 361 double originY = y; 362 x = vals[2]; 363 y = vals[3]; 364 quadraticBezierAbsolute(originX, originY, vals[0], vals[1], x, y, sb); 365 break; 366 default: 367 break; 368 } 369 iter.next(); 370 } 371 sb.append("\n"); 372 gen.writeText(sb.toString()); 373 } 374 375 380 public void processPathIteratorFill(PathIterator iter) throws IOException { 381 gen.writeText("\n"); 382 double[] vals = new double[6]; 383 boolean penDown = false; 384 double x = 0; 385 double y = 0; 386 boolean pendingPM0 = true; 387 StringBuffer sb = new StringBuffer (256); 388 penUp(sb); 389 while (!iter.isDone()) { 390 int type = iter.currentSegment(vals); 391 if (type == PathIterator.SEG_CLOSE) { 392 sb.append("PM1;"); 393 iter.next(); 394 continue; 395 } else if (type == PathIterator.SEG_MOVETO) { 396 if (penDown) { 397 penUp(sb); 398 penDown = false; 399 } 400 } else { 401 if (!penDown) { 402 penDown(sb); 403 penDown = true; 404 } 405 } 406 switch (type) { 407 case PathIterator.SEG_MOVETO: 408 x = vals[0]; 409 y = vals[1]; 410 plotAbsolute(x, y, sb); 411 break; 412 case PathIterator.SEG_LINETO: 413 x = vals[0]; 414 y = vals[1]; 415 plotAbsolute(x, y, sb); 416 break; 417 case PathIterator.SEG_CUBICTO: 418 x = vals[4]; 419 y = vals[5]; 420 bezierAbsolute(vals[0], vals[1], vals[2], vals[3], x, y, sb); 421 break; 422 case PathIterator.SEG_QUADTO: 423 double originX = x; 424 double originY = y; 425 x = vals[2]; 426 y = vals[3]; 427 quadraticBezierAbsolute(originX, originY, vals[0], vals[1], x, y, sb); 428 break; 429 default: 430 throw new IllegalStateException ("Must not get here"); 431 } 432 if (pendingPM0) { 433 pendingPM0 = false; 434 sb.append("PM;"); 435 } 436 iter.next(); 437 } 438 sb.append("PM2;"); 439 fillPolygon(iter.getWindingRule(), sb); 440 sb.append("\n"); 441 gen.writeText(sb.toString()); 442 } 443 444 private void fillPolygon(int windingRule, StringBuffer sb) { 445 int fillMethod = (windingRule == PathIterator.WIND_EVEN_ODD ? 0 : 1); 446 sb.append("FP").append(fillMethod).append(";"); 447 } 448 449 private void plotAbsolute(double x, double y, StringBuffer sb) { 450 sb.append("PA").append(gen.formatDouble4(x)); 451 sb.append(",").append(gen.formatDouble4(y)).append(";"); 452 } 453 454 private void bezierAbsolute(double x1, double y1, double x2, double y2, double x3, double y3, 455 StringBuffer sb) { 456 sb.append("BZ").append(gen.formatDouble4(x1)); 457 sb.append(",").append(gen.formatDouble4(y1)); 458 sb.append(",").append(gen.formatDouble4(x2)); 459 sb.append(",").append(gen.formatDouble4(y2)); 460 sb.append(",").append(gen.formatDouble4(x3)); 461 sb.append(",").append(gen.formatDouble4(y3)).append(";"); 462 } 463 464 private void quadraticBezierAbsolute(double originX, double originY, 465 double x1, double y1, double x2, double y2, StringBuffer sb) { 466 double nx1 = originX + (2.0 / 3.0) * (x1 - originX); 469 double ny1 = originY + (2.0 / 3.0) * (y1 - originY); 470 471 double nx2 = nx1 + (1.0 / 3.0) * (x2 - originX); 472 double ny2 = ny1 + (1.0 / 3.0) * (y2 - originY); 473 474 bezierAbsolute(nx1, ny1, nx2, ny2, x2, y2, sb); 475 } 476 477 private void penDown(StringBuffer sb) { 478 sb.append("PD;"); 479 } 480 481 private void penUp(StringBuffer sb) { 482 sb.append("PU;"); 483 } 484 485 486 public void drawString(String s, float x, float y) { 487 java.awt.Font awtFont = getFont(); 488 FontRenderContext frc = getFontRenderContext(); 489 GlyphVector gv = awtFont.createGlyphVector(frc, s); 490 Shape glyphOutline = gv.getOutline(x, y); 491 fill(glyphOutline); 492 } 493 494 495 public void drawString(AttributedCharacterIterator iterator, float x, 496 float y) { 497 handleUnsupportedFeature("drawString NYI"); 499 } 500 501 505 public void drawRenderedImage(RenderedImage img, AffineTransform xform) { 506 handleUnsupportedFeature("Bitmap images are not supported"); 507 } 508 509 513 public void drawRenderableImage(RenderableImage img, AffineTransform xform) { 514 handleUnsupportedFeature("Bitmap images are not supported"); 515 } 516 517 521 public boolean drawImage(Image img, int x, int y, int width, int height, 522 ImageObserver observer) { 523 handleUnsupportedFeature("Bitmap images are not supported"); 524 return false; 525 } 526 527 530 public boolean drawImage(Image img, int x, int y, ImageObserver observer) { 531 handleUnsupportedFeature("Bitmap images are not supported"); 532 return false; 533 575 } 576 577 578 public void copyArea(int x, int y, int width, int height, int dx, int dy) { 579 handleUnsupportedFeature("copyArea NYI"); 581 } 582 583 584 public void setXORMode(Color c1) { 585 handleUnsupportedFeature("setXORMode NYI"); 587 } 588 589 592 private Graphics2D fmg; 593 594 { 595 BufferedImage bi = new BufferedImage (1, 1, 596 BufferedImage.TYPE_INT_ARGB); 597 598 fmg = bi.createGraphics(); 599 } 600 601 606 protected BufferedImage buildBufferedImage(Dimension size) { 607 return new BufferedImage (size.width, size.height, 608 BufferedImage.TYPE_BYTE_GRAY); 609 } 610 611 612 public java.awt.FontMetrics getFontMetrics(java.awt.Font f) { 613 return fmg.getFontMetrics(f); 614 } 615 616 } 617 | Popular Tags |