1 51 package org.apache.fop.render.pcl; 52 53 import org.apache.fop.render.PrintRenderer; 55 import org.apache.fop.fo.properties.*; 56 import org.apache.fop.datatypes.*; 57 import org.apache.fop.pdf.PDFPathPaint; 58 import org.apache.fop.pdf.PDFColor; 59 import org.apache.fop.layout.*; 60 import org.apache.fop.layout.inline.*; 61 import org.apache.fop.image.*; 62 import org.apache.fop.svg.SVGArea; 63 64 import org.w3c.dom.svg.SVGSVGElement; 65 import org.w3c.dom.svg.SVGDocument; 66 67 import java.io.IOException ; 69 import java.io.OutputStream ; 70 71 79 public class PCLRenderer extends PrintRenderer { 80 81 84 public PCLStream currentStream; 85 86 private int pageHeight = 7920; 87 88 public int curdiv = 0; 90 private int divisions = -1; 91 public int paperheight = -1; public int orientation = 0; public int topmargin = -1; public int leftmargin = -1; private int fullmargin = 0; 96 private final boolean debug = false; 97 98 private int xoffset = 99 -180; 101 private java.util.Map options; 102 103 106 public PCLRenderer() {} 107 108 111 public void setOptions(java.util.Map options) { 112 this.options = options; 113 } 114 115 120 public void setProducer(String producer) {} 121 122 132 protected void addLine(int x1, int y1, int x2, int y2, int th, 133 PDFPathPaint stroke) { 134 if (x1 == x2) 135 addRect(x1 - (th / 2), y1, th, y2 - y1 + 1, stroke, stroke); 136 else if (y1 == y2) 137 addRect(x1, y1 + (th / 2), x2 - x1 + 1, th, stroke, stroke); 138 } 139 140 151 protected void addLine(int x1, int y1, int x2, int y2, int th, int rs, 152 PDFPathPaint stroke) { 153 int dashon = 0; 154 int dashoff = 0; 155 switch (rs) { 161 case org.apache.fop.fo.properties.RuleStyle.DASHED: 162 dashon = 3; 163 dashoff = 3; 164 break; 165 case org.apache.fop.fo.properties.RuleStyle.DOTTED: 166 dashon = 1; 167 dashoff = 3; 168 break; 169 } 170 if (x1 == x2) { 171 if (dashon > 0 && dashoff > 0) { 172 int start = y1; 173 int len = th * dashon; 174 while (start < y2) { 175 if (start + len > y2) 176 len = y2 - start; 177 addRect(x1 - (th / 2), start, th, len, stroke, stroke); 178 start += (len + dashoff * th); 179 } 180 } else 181 addRect(x1 - (th / 2), y1, th, y2 - y1 + 1, stroke, stroke); 182 } else if (y1 == y2) { 183 if (dashon > 0 && dashoff > 0) { 184 int start = x1; 185 int len = th * dashon; 186 while (start < x2) { 187 if (start + len > x2) 188 len = x2 - start; 189 addRect(start, y1 + (th / 2), len, th, stroke, stroke); 190 start += (len + dashoff * th); 191 } 192 } else 193 addRect(x1, y1 + (th / 2), x2 - x1 + 1, th, stroke, stroke); 194 } 195 } 196 197 206 protected void addRect(int x, int y, int w, int h, PDFPathPaint stroke) { 207 210 if ((h >= 0 && h < 720) || (h < 0 && h > -720) || w < 720) { 211 if (w < 720) 212 w = 720; 213 if (h > 0 && h < 720) 214 h = 720; 215 else if (h < 0 && h > -720) 216 h = -720; 217 addRect(x, y, w, h, stroke, stroke); 218 } else { 219 addRect(x, y, w, 720, stroke, stroke); 220 addRect(x, y, 720, h, stroke, stroke); 221 addRect(x + w - 720, y, 720, h, stroke, stroke); 222 addRect(x, y - h + 720, w, 720, stroke, stroke); 223 } 224 } 225 226 236 protected void addRect(int x, int y, int w, int h, PDFPathPaint stroke, 237 PDFPathPaint fill) { 238 if ((w == 0) || (h == 0)) 239 return; 240 if (h < 0) 241 h *= -1; 242 else 243 y += h; 244 245 246 PDFColor sc = (PDFColor)stroke; 247 PDFColor fc = (PDFColor)fill; 248 249 sc.setColorSpace(ColorSpace.DEVICE_RGB); 250 fc.setColorSpace(ColorSpace.DEVICE_RGB); 251 252 int lineshade = 253 (int)(100 254 - ((0.3f * sc.red() + 0.59f * sc.green() + 0.11f * sc.blue()) 255 * 100f)); 256 int fillshade = 257 (int)(100 258 - ((0.3f * fc.red() + 0.59f * fc.green() + 0.11f * fc.blue()) 259 * 100f)); 260 261 int xpos = xoffset + (x / 100); 262 if (xpos < 0) { 263 xpos = 0; 264 log.warn("Horizontal position out of bounds."); 265 } 266 267 currentStream.add("\033*v1O\033&a" + xpos + "h" 268 + (pageHeight - (y / 100)) + "V" + "\033*c" 269 + (w / 100) + "h" + (h / 100) + "V" + "\033*c" 270 + lineshade + "G" + "\033*c2P"); 271 if (fillshade != lineshade && (w >= 720 || h >= 720)) { 272 xpos = xoffset + ((x + 240) / 100); 273 if (xpos < 0) { 274 xpos = 0; 275 log.warn("Horizontal position out of bounds."); 276 } 277 currentStream.add("\033&a" + xpos + "h" 278 + (pageHeight - ((y + 240)) / 100) + "V" 279 + "\033*c" + ((w - 480) / 100) + "h" 280 + ((h - 480) / 100) + "V" + "\033*c" 281 + fillshade + "G" + "\033*c2P"); 282 } 283 currentStream.add("\033*v0O"); 285 } 286 287 300 protected void drawImageScaled(int x, int y, int w, int h, 301 FopImage image, 302 FontState fs) { 303 } 305 306 319 protected void drawImageClipped(int x, int y, 320 int clipX, int clipY, 321 int clipW, int clipH, 322 FopImage image, 323 FontState fs) { 324 } 326 327 boolean printBMP(FopImage img, int x, int y, int w, 328 int h) throws FopImageException { 329 byte imgmap[] = img.getBitmaps(); 331 332 int ix = 0; 333 int iy = 0; 334 int indx = 0; 335 int iw = img.getWidth(); 336 int ih = img.getHeight(); 337 int bytewidth = (iw / 8); 338 if ((iw % 8) != 0) 339 bytewidth++; 340 byte ib; 341 char ic[] = new char[bytewidth * 2]; 342 char icu[] = new char[bytewidth]; 343 int lastcount = -1; 344 byte lastbyte = 0; 345 int icwidth = 0; 346 int cr = 0; 347 int cg = 0; 348 int cb = 0; 349 int grey = 0; 350 boolean iscolor = img.getColorSpace().getColorSpace() 351 != ColorSpace.DEVICE_GRAY; 352 int dcount = 0; 353 int xres = (iw * 72000) / w; 354 int yres = (ih * 72000) / h; 355 int resolution = xres; 356 if (yres > xres) 357 resolution = yres; 358 359 if (resolution > 300) 360 resolution = 600; 361 else if (resolution > 150) 362 resolution = 300; 363 else if (resolution > 100) 364 resolution = 150; 365 else if (resolution > 75) 366 resolution = 100; 367 else 368 resolution = 75; 369 if (debug) 370 System.out.println("PCLRenderer.printBMP() iscolor = " + iscolor); 371 currentStream.add("\033*t" + resolution + "R\033*r0F\033*r1A"); 373 374 for (iy = 0; iy < ih; iy++) { 376 ib = 0; 377 indx = iy * iw; 383 if (iscolor) 384 indx *= 3; 385 for (ix = 0; ix < iw; ix++) { 387 if (iscolor) { 388 cr = imgmap[indx++] & 0xFF; 389 cg = imgmap[indx++] & 0xFF; 390 cb = imgmap[indx++] & 0xFF; 391 grey = (cr * 30 + cg * 59 + cb * 11) / 100; 392 } else 393 grey = imgmap[indx++] & 0xFF; 394 if (grey < 128) 395 ib |= (1 << (7 - (ix % 8))); 396 if ((ix % 8) == 7 || ((ix + 1) == iw)) { 397 if (icwidth < bytewidth) { 398 if (lastcount >= 0) { 399 if (ib == lastbyte) 400 lastcount++; 401 else { 402 ic[icwidth++] = (char)(lastcount & 0xFF); 403 ic[icwidth++] = (char)lastbyte; 404 lastbyte = ib; 405 lastcount = 0; 406 } 407 } else { 408 lastbyte = ib; 409 lastcount = 0; 410 } 411 if (lastcount == 255 || ((ix + 1) == iw)) { 412 ic[icwidth++] = (char)(lastcount & 0xFF); 413 ic[icwidth++] = (char)lastbyte; 414 lastbyte = 0; 415 lastcount = -1; 416 } 417 } 418 icu[ix / 8] = (char)ib; 419 ib = 0; 420 } 421 } 422 if (icwidth < bytewidth) { 423 currentStream.add("\033*b1m" + icwidth + "W"); 424 currentStream.add(new String (ic, 0, icwidth)); 425 } else { 426 currentStream.add("\033*b0m" + bytewidth + "W"); 427 currentStream.add(new String (icu)); 428 } 429 lastcount = -1; 430 icwidth = 0; 431 } 432 433 currentStream.add("\033*rB"); 435 436 437 return (true); 438 } 439 440 445 public void renderImageArea(ImageArea area) { 446 int x = this.currentAreaContainerXPosition + area.getXOffset(); 447 int y = this.currentYPosition; 448 int w = area.getContentWidth(); 449 int h = area.getHeight(); 450 451 this.currentYPosition -= h; 452 453 FopImage img = area.getImage(); 454 455 int xpos = xoffset + (x / 100); 456 if (xpos < 0) { 457 xpos = 0; 458 log.warn("Horizontal position out of bounds."); 459 } 460 461 currentStream.add("\033&a" + xpos + "h" + (pageHeight - (y / 100)) 462 + "V"); 463 464 try { 465 printBMP(img, x, y, w, h); 466 } catch (FopImageException e) { 467 log.error("PCLRenderer.renderImageArea() Error printing BMP (" 469 + e.toString() + ")"); 470 } 471 } 472 473 476 public void renderForeignObjectArea(ForeignObjectArea area) { 477 this.currentXPosition = this.currentXPosition + area.getXOffset(); 479 this.currentYPosition = this.currentYPosition; 480 switch (area.getAlign()) { 481 case TextAlign.START: 482 break; 483 case TextAlign.END: 484 break; 485 case TextAlign.CENTER: 486 case TextAlign.JUSTIFY: 487 break; 488 } 489 switch (area.getVerticalAlign()) { 490 case VerticalAlign.BASELINE: 491 break; 492 case VerticalAlign.MIDDLE: 493 break; 494 case VerticalAlign.SUB: 495 break; 496 case VerticalAlign.SUPER: 497 break; 498 case VerticalAlign.TEXT_TOP: 499 break; 500 case VerticalAlign.TEXT_BOTTOM: 501 break; 502 case VerticalAlign.TOP: 503 break; 504 case VerticalAlign.BOTTOM: 505 break; 506 } 507 509 511 switch (area.scalingMethod()) { 512 case Scaling.UNIFORM: 513 break; 514 case Scaling.NON_UNIFORM: 515 break; 516 } 517 switch (area.getOverflow()) { 521 case Overflow.VISIBLE: 522 case Overflow.SCROLL: 523 case Overflow.AUTO: 524 break; 525 case Overflow.HIDDEN: 526 break; 527 } 528 area.getObject().render(this); 529 530 this.currentXPosition += area.getEffectiveWidth(); 531 } 533 534 539 public void renderSVGArea(SVGArea area) { 540 if (debug) 541 System.out.println("PCLRenderer.renderSVGArea(" + area + ")"); 542 int x = this.currentXPosition; 543 int y = this.currentYPosition; 544 SVGSVGElement svg = 545 ((SVGDocument)area.getSVGDocument()).getRootElement(); 546 int w = (int)(svg.getWidth().getBaseVal().getValue() * 1000); 547 int h = (int)(svg.getHeight().getBaseVal().getValue() * 1000); 548 549 554 555 557 559 } 561 562 563 public void setFont(String name, float size) { 564 int fontcode = 0; 565 if (name.length() > 1 && name.charAt(0) == 'F') { 566 try { 567 fontcode = Integer.parseInt(name.substring(1)); 568 } catch (Exception e) { 569 e.printStackTrace(); 570 } 571 } 572 switch (fontcode) { 573 case 1: 577 currentStream.add("\033(0N\033(s1p" + (size / 1000) 578 + "v0s0b16602T"); 579 break; 580 case 2: 582 currentStream.add("\033(0N\033(s1p" + (size / 1000) 583 + "v1s0b16602T"); 584 break; 585 case 3: 587 currentStream.add("\033(0N\033(s1p" + (size / 1000) 588 + "v0s3b16602T"); 589 break; 590 case 4: 592 currentStream.add("\033(0N\033(s1p" + (size / 1000) 593 + "v1s3b16602T"); 594 break; 595 case 5: 599 currentStream.add("\033(0N\033(s1p" + (size / 1000) 600 + "v0s0b16901T"); 601 break; 602 case 6: 604 currentStream.add("\033(0N\033(s1p" + (size / 1000) 605 + "v1s0b16901T"); 606 break; 607 case 7: 609 currentStream.add("\033(0N\033(s1p" + (size / 1000) 610 + "v0s3b16901T"); 611 break; 612 case 8: 614 currentStream.add("\033(0N\033(s1p" + (size / 1000) 615 + "v1s3b16901T"); 616 break; 617 case 9: 619 currentStream.add("\033(0N\033(s0p" 620 + (120.01f / (size / 1000.00f)) + "h0s0b4099T"); 621 break; 622 case 10: 624 currentStream.add("\033(0N\033(s0p" 625 + (120.01f / (size / 1000.00f)) + "h1s0b4099T"); 626 break; 627 case 11: 629 currentStream.add("\033(0N\033(s0p" 630 + (120.01f / (size / 1000.00f)) + "h0s3b4099T"); 631 break; 632 case 12: 634 currentStream.add("\033(0N\033(s0p" 635 + (120.01f / (size / 1000.00f)) + "h1s3b4099T"); 636 break; 637 case 13: 639 currentStream.add("\033(19M\033(s1p" + (size / 1000) 640 + "v0s0b16686T"); 641 break; 643 case 14: 645 currentStream.add("\033(14L\033(s1p" + (size / 1000) 646 + "v0s0b45101T"); 647 break; 648 default: 649 currentStream.add("\033(0N\033(s" + (size / 1000) + "V"); 650 break; 651 } 652 } 653 654 659 public void renderWordArea(WordArea area) { 660 String name = area.getFontState().getFontName(); 661 int size = area.getFontState().getFontSize(); 662 663 float red = area.getRed(); 664 float green = area.getGreen(); 665 float blue = area.getBlue(); 666 PDFColor theAreaColor = new PDFColor((double)area.getRed(), 667 (double)area.getGreen(), 668 (double)area.getBlue()); 669 670 currentStream.add("\033*v1O\033*c" 672 + (int)(100 - ((0.3f * red + 0.59f * green + 0.11f * blue) * 100f)) 673 + "G\033*v2T"); 674 675 if ((!name.equals(this.currentFontName)) 676 || (size != this.currentFontSize)) { 677 this.currentFontName = name; 678 this.currentFontSize = size; 679 setFont(name, size); 680 } 681 682 this.currentFill = theAreaColor; 683 684 int rx = this.currentXPosition; 685 int bl = this.currentYPosition; 686 687 String s = area.getText(); 688 689 addWordLines(area, rx, bl, size, theAreaColor); 690 691 int xpos = xoffset + (rx / 100); 692 if (xpos < 0) { 693 xpos = 0; 694 log.warn("Horizontal position out of bounds."); 695 } 696 currentStream.add("\033&a" + xpos + "h" + (pageHeight - (bl / 100)) 697 + "V" + s); 698 699 this.currentXPosition += area.getContentWidth(); 700 } 701 702 707 public void renderPage(Page page) { 708 if (debug) 709 System.out.println("PCLRenderer.renderPage() page.Height() = " 710 + page.getHeight()); 711 712 if (page.getHeight() < page.getWidth()) { 715 orientation = 1; 716 } 717 currentStream.add("\033&l" + orientation + "O"); 718 if (orientation == 1 || orientation == 3) { 719 xoffset = -144; 720 } else { 721 xoffset = -180; 722 } 723 724 if (paperheight > 0 && divisions == -1) 725 divisions = paperheight / (page.getHeight() / 100); 726 727 if (debug) 728 System.out.println("PCLRenderer.renderPage() paperheight=" 729 + paperheight + " divisions=" + divisions); 730 731 if (divisions > 0) 734 fullmargin = paperheight * curdiv / divisions; 735 if (topmargin > 0) 736 fullmargin += topmargin; 737 if (debug) 738 System.out.println("PCLRenderer.renderPage() curdiv=" + curdiv 739 + " fullmargin=" + fullmargin); 740 744 if (paperheight > 0) 745 pageHeight = (paperheight / divisions) + fullmargin; 746 else 747 pageHeight = page.getHeight() / 100; 748 if (debug) 749 System.out.println("PCLRenderer.renderPage() Set currentYPosition=" 750 + this.currentYPosition); 751 if (leftmargin > 0 && curdiv == 0) 752 currentStream.add("\033&k" + (leftmargin / 6f) 753 + "H\033&a1L\033&k12H"); 754 755 this.currentFontName = ""; 756 this.currentFontSize = 0; 757 758 renderRegions(page); 759 760 if (++curdiv == divisions || divisions == -1) { 762 curdiv = 0; 763 currentStream.add("\f"); 764 } 765 766 791 } 792 public void startRenderer(OutputStream outputStream) 793 throws IOException { 794 log.info("rendering areas to PCL"); 795 currentStream = new PCLStream(outputStream); 796 797 currentStream.add("\033" + "9\033&l0E"); 799 } 800 801 public void stopRenderer(OutputStream outputStream) 802 throws IOException { 803 log.info("writing out PCL"); 804 outputStream.flush(); 805 } 806 807 public void render(Page page, OutputStream outputStream) 808 throws IOException { 809 idReferences = page.getIDReferences(); 810 this.renderPage(page); 811 } 812 813 } 814 | Popular Tags |