1 28 29 37 package net.sf.jasperreports.engine.export; 38 39 import java.awt.Color ; 40 import java.awt.Graphics2D ; 41 import java.awt.font.TextAttribute ; 42 import java.awt.geom.AffineTransform ; 43 import java.awt.geom.Dimension2D ; 44 import java.awt.geom.Rectangle2D ; 45 import java.awt.image.BufferedImage ; 46 import java.io.File ; 47 import java.io.FileOutputStream ; 48 import java.io.IOException ; 49 import java.io.OutputStream ; 50 import java.text.AttributedCharacterIterator ; 51 import java.util.Collection ; 52 import java.util.HashMap ; 53 import java.util.Iterator ; 54 import java.util.LinkedList ; 55 import java.util.List ; 56 import java.util.Map ; 57 58 import net.sf.jasperreports.engine.JRAbstractExporter; 59 import net.sf.jasperreports.engine.JRAlignment; 60 import net.sf.jasperreports.engine.JRAnchor; 61 import net.sf.jasperreports.engine.JRBox; 62 import net.sf.jasperreports.engine.JRElement; 63 import net.sf.jasperreports.engine.JRException; 64 import net.sf.jasperreports.engine.JRExporterParameter; 65 import net.sf.jasperreports.engine.JRFont; 66 import net.sf.jasperreports.engine.JRGraphicElement; 67 import net.sf.jasperreports.engine.JRHyperlink; 68 import net.sf.jasperreports.engine.JRImage; 69 import net.sf.jasperreports.engine.JRImageRenderer; 70 import net.sf.jasperreports.engine.JRLine; 71 import net.sf.jasperreports.engine.JRPrintAnchor; 72 import net.sf.jasperreports.engine.JRPrintElement; 73 import net.sf.jasperreports.engine.JRPrintEllipse; 74 import net.sf.jasperreports.engine.JRPrintFrame; 75 import net.sf.jasperreports.engine.JRPrintGraphicElement; 76 import net.sf.jasperreports.engine.JRPrintHyperlink; 77 import net.sf.jasperreports.engine.JRPrintImage; 78 import net.sf.jasperreports.engine.JRPrintLine; 79 import net.sf.jasperreports.engine.JRPrintPage; 80 import net.sf.jasperreports.engine.JRPrintRectangle; 81 import net.sf.jasperreports.engine.JRPrintText; 82 import net.sf.jasperreports.engine.JRRenderable; 83 import net.sf.jasperreports.engine.JRRuntimeException; 84 import net.sf.jasperreports.engine.JRTextElement; 85 import net.sf.jasperreports.engine.JasperPrint; 86 import net.sf.jasperreports.engine.base.JRBaseFont; 87 import net.sf.jasperreports.engine.util.BreakIteratorSplitCharacter; 88 import net.sf.jasperreports.engine.util.JRLoader; 89 import net.sf.jasperreports.engine.util.JRProperties; 90 import net.sf.jasperreports.engine.util.JRStyledText; 91 92 import com.lowagie.text.Chunk; 93 import com.lowagie.text.Document; 94 import com.lowagie.text.DocumentException; 95 import com.lowagie.text.Element; 96 import com.lowagie.text.Font; 97 import com.lowagie.text.FontFactory; 98 import com.lowagie.text.Image; 99 import com.lowagie.text.Phrase; 100 import com.lowagie.text.Rectangle; 101 import com.lowagie.text.SplitCharacter; 102 import com.lowagie.text.pdf.BaseFont; 103 import com.lowagie.text.pdf.ColumnText; 104 import com.lowagie.text.pdf.FontMapper; 105 import com.lowagie.text.pdf.PdfContentByte; 106 import com.lowagie.text.pdf.PdfDestination; 107 import com.lowagie.text.pdf.PdfOutline; 108 import com.lowagie.text.pdf.PdfTemplate; 109 import com.lowagie.text.pdf.PdfWriter; 110 111 112 128 public class JRPdfExporter extends JRAbstractExporter 129 { 130 131 138 public static final String PDF_FORCE_SVG_SHAPES = JRProperties.PROPERTY_PREFIX + "export.pdf.force.svg.shapes"; 139 140 private static final String EMPTY_BOOKMARK_TITLE = ""; 141 142 145 protected static final String JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_"; 146 147 protected static boolean fontsRegistered = false; 148 149 152 protected Document document = null; 153 protected PdfContentByte pdfContentByte = null; 154 155 protected Document imageTesterDocument = null; 156 protected PdfContentByte imageTesterPdfContentByte = null; 157 158 protected JRExportProgressMonitor progressMonitor = null; 159 160 protected int reportIndex = 0; 161 162 165 protected boolean isCreatingBatchModeBookmarks = false; 166 protected boolean isCompressed = false; 167 protected boolean isEncrypted = false; 168 protected boolean is128BitKey = false; 169 protected String userPassword = null; 170 protected String ownerPassword = null; 171 protected int permissions = 0; 172 protected Character pdfVersion = null; 173 174 177 protected Map loadedImagesMap = null; 178 protected Image pxImage = null; 179 180 private BookmarkStack bookmarkStack = null; 181 182 private Map fontMap = null; 183 184 private boolean forceSvgShapes = true; 185 private SplitCharacter splitCharacter; 186 protected JRHyperlinkProducerFactory hyperlinkProducerFactory; 187 188 private String pdfJavaScript; 189 190 193 protected Image getPxImage() 194 { 195 if (pxImage == null) 196 { 197 try 198 { 199 pxImage = 200 Image.getInstance( 201 JRLoader.loadBytesFromLocation("net/sf/jasperreports/engine/images/pixel.GIF", null) 202 ); 203 } 204 catch(Exception e) 205 { 206 throw new JRRuntimeException(e); 207 } 208 } 209 210 return pxImage; 211 } 212 213 214 217 public void exportReport() throws JRException 218 { 219 registerFonts(); 220 221 progressMonitor = (JRExportProgressMonitor)parameters.get(JRExporterParameter.PROGRESS_MONITOR); 222 223 224 setOffset(); 225 226 try 227 { 228 229 setExportContext(); 230 231 232 setInput(); 233 234 235 if (!isModeBatch) 236 { 237 setPageRange(); 238 } 239 240 Boolean isCreatingBatchModeBookmarksParameter = (Boolean )parameters.get(JRPdfExporterParameter.IS_CREATING_BATCH_MODE_BOOKMARKS); 241 if(isCreatingBatchModeBookmarksParameter != null){ 242 isCreatingBatchModeBookmarks = isCreatingBatchModeBookmarksParameter.booleanValue(); 243 } 244 245 Boolean isCompressedParameter = (Boolean )parameters.get(JRPdfExporterParameter.IS_COMPRESSED); 246 if (isCompressedParameter != null) 247 { 248 isCompressed = isCompressedParameter.booleanValue(); 249 } 250 251 Boolean isEncryptedParameter = (Boolean )parameters.get(JRPdfExporterParameter.IS_ENCRYPTED); 252 if (isEncryptedParameter != null) 253 { 254 isEncrypted = isEncryptedParameter.booleanValue(); 255 } 256 257 Boolean is128BitKeyParameter = (Boolean )parameters.get(JRPdfExporterParameter.IS_128_BIT_KEY); 258 if (is128BitKeyParameter != null) 259 { 260 is128BitKey = is128BitKeyParameter.booleanValue(); 261 } 262 263 userPassword = (String )parameters.get(JRPdfExporterParameter.USER_PASSWORD); 264 ownerPassword = (String )parameters.get(JRPdfExporterParameter.OWNER_PASSWORD); 265 266 Integer permissionsParameter = (Integer )parameters.get(JRPdfExporterParameter.PERMISSIONS); 267 if (permissionsParameter != null) 268 { 269 permissions = permissionsParameter.intValue(); 270 } 271 272 pdfVersion = (Character ) parameters.get(JRPdfExporterParameter.PDF_VERSION); 273 274 fontMap = (Map ) parameters.get(JRExporterParameter.FONT_MAP); 275 276 setForceSvgShapes(); 277 setSplitCharacter(); 278 setHyperlinkProducerFactory(); 279 280 pdfJavaScript = (String )parameters.get(JRPdfExporterParameter.PDF_JAVASCRIPT); 281 282 OutputStream os = (OutputStream )parameters.get(JRExporterParameter.OUTPUT_STREAM); 283 if (os != null) 284 { 285 exportReportToStream(os); 286 } 287 else 288 { 289 File destFile = (File )parameters.get(JRExporterParameter.OUTPUT_FILE); 290 if (destFile == null) 291 { 292 String fileName = (String )parameters.get(JRExporterParameter.OUTPUT_FILE_NAME); 293 if (fileName != null) 294 { 295 destFile = new File (fileName); 296 } 297 else 298 { 299 throw new JRException("No output specified for the exporter."); 300 } 301 } 302 303 try 304 { 305 os = new FileOutputStream (destFile); 306 exportReportToStream(os); 307 os.flush(); 308 } 309 catch (IOException e) 310 { 311 throw new JRException("Error trying to export to file : " + destFile, e); 312 } 313 finally 314 { 315 if (os != null) 316 { 317 try 318 { 319 os.close(); 320 } 321 catch(IOException e) 322 { 323 } 324 } 325 } 326 } 327 } 328 finally 329 { 330 resetExportContext(); 331 } 332 } 333 334 335 protected void setForceSvgShapes() 336 { 337 Boolean forceSvgShapesParam = (Boolean ) parameters.get(JRPdfExporterParameter.FORCE_SVG_SHAPES); 338 if (forceSvgShapesParam == null) 339 { 340 forceSvgShapes = JRProperties.getBooleanProperty(PDF_FORCE_SVG_SHAPES); 341 } 342 else 343 { 344 forceSvgShapes = forceSvgShapesParam.booleanValue(); 345 } 346 } 347 348 349 protected void setSplitCharacter() 350 { 351 boolean useFillSplitCharacter; 352 Boolean useFillSplitCharacterParam = (Boolean ) parameters.get(JRPdfExporterParameter.FORCE_LINEBREAK_POLICY); 353 if (useFillSplitCharacterParam == null) 354 { 355 useFillSplitCharacter = JRProperties.getBooleanProperty(JRProperties.PDF_FORCE_LINEBREAK_POLICY); 356 } 357 else 358 { 359 useFillSplitCharacter = useFillSplitCharacterParam.booleanValue(); 360 } 361 362 if (useFillSplitCharacter) 363 { 364 splitCharacter = new BreakIteratorSplitCharacter(); 365 } 366 } 367 368 369 protected void setHyperlinkProducerFactory() 370 { 371 hyperlinkProducerFactory = (JRHyperlinkProducerFactory) parameters.get(JRPdfExporterParameter.HYPERLINK_PRODUCER_FACTORY); 372 } 373 374 375 378 protected void exportReportToStream(OutputStream os) throws JRException 379 { 380 382 document = 383 new Document( 384 new Rectangle( 385 jasperPrint.getPageWidth(), 386 jasperPrint.getPageHeight() 387 ) 388 ); 389 390 imageTesterDocument = 391 new Document( 392 new Rectangle( 393 10, 10 ) 396 ); 397 398 try 399 { 400 PdfWriter pdfWriter = PdfWriter.getInstance(document, os); 401 pdfWriter.setCloseStream(false); 402 403 if (pdfVersion != null) 404 pdfWriter.setPdfVersion(pdfVersion.charValue()); 405 406 if (isCompressed) 407 pdfWriter.setFullCompression(); 408 409 if (isEncrypted) 410 { 411 pdfWriter.setEncryption( 412 is128BitKey, 413 userPassword, 414 ownerPassword, 415 permissions 416 ); 417 } 418 419 String title = (String )parameters.get(JRPdfExporterParameter.METADATA_TITLE); 422 if( title != null ) 423 document.addTitle(title); 424 425 String author = (String )parameters.get(JRPdfExporterParameter.METADATA_AUTHOR); 426 if( author != null ) 427 document.addAuthor(author); 428 429 String subject = (String )parameters.get(JRPdfExporterParameter.METADATA_SUBJECT); 430 if( subject != null ) 431 document.addSubject(subject); 432 433 String keywords = (String )parameters.get(JRPdfExporterParameter.METADATA_KEYWORDS); 434 if( keywords != null ) 435 document.addKeywords(keywords); 436 437 String creator = (String )parameters.get(JRPdfExporterParameter.METADATA_CREATOR); 438 if( creator != null ) 439 document.addCreator(creator); 440 else 441 document.addCreator("JasperReports (" + jasperPrint.getName() + ")"); 442 443 document.open(); 444 445 if(pdfJavaScript != null) 446 pdfWriter.addJavaScript(pdfJavaScript); 447 448 pdfContentByte = pdfWriter.getDirectContent(); 449 450 initBookmarks(); 451 452 PdfWriter imageTesterPdfWriter = 453 PdfWriter.getInstance( 454 imageTesterDocument, 455 new NullOutputStream() ); 457 imageTesterDocument.open(); 458 imageTesterDocument.newPage(); 459 imageTesterPdfContentByte = imageTesterPdfWriter.getDirectContent(); 460 imageTesterPdfContentByte.setLiteral("\n"); 461 462 for(reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++) 463 { 464 jasperPrint = (JasperPrint)jasperPrintList.get(reportIndex); 465 loadedImagesMap = new HashMap (); 466 document.setPageSize(new Rectangle(jasperPrint.getPageWidth(), jasperPrint.getPageHeight())); 467 468 List pages = jasperPrint.getPages(); 469 if (pages != null && pages.size() > 0) 470 { 471 if (isModeBatch) 472 { 473 document.newPage(); 474 475 if( isCreatingBatchModeBookmarks ){ 476 addBookmark(0, jasperPrint.getName(), 0, 0); 478 } 479 480 startPageIndex = 0; 481 endPageIndex = pages.size() - 1; 482 } 483 484 Chunk chunk = null; 485 ColumnText colText = null; 486 JRPrintPage page = null; 487 for(int pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++) 488 { 489 if (Thread.currentThread().isInterrupted()) 490 { 491 throw new JRException("Current thread interrupted."); 492 } 493 494 page = (JRPrintPage)pages.get(pageIndex); 495 496 document.newPage(); 497 498 pdfContentByte = pdfWriter.getDirectContent(); 499 500 pdfContentByte.setLineCap(2); 502 chunk = new Chunk(" "); 503 chunk.setLocalDestination(JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + (pageIndex + 1)); 504 505 colText = new ColumnText(pdfContentByte); 506 colText.setSimpleColumn( 507 new Phrase(chunk), 508 0, 509 jasperPrint.getPageHeight(), 510 1, 511 1, 512 0, 513 Element.ALIGN_LEFT 514 ); 515 516 colText.go(); 517 518 519 exportPage(page); 520 } 521 } 522 else 523 { 524 document.newPage(); 525 pdfContentByte = pdfWriter.getDirectContent(); 526 pdfContentByte.setLiteral("\n"); 527 } 528 } 529 } 530 catch(DocumentException e) 531 { 532 throw new JRException("PDF Document error : " + jasperPrint.getName(), e); 533 } 534 catch(IOException e) 535 { 536 throw new JRException("Error generating PDF report : " + jasperPrint.getName(), e); 537 } 538 finally 539 { 540 document.close(); 541 imageTesterDocument.close(); 542 } 543 544 } 546 547 548 551 protected void exportPage(JRPrintPage page) throws JRException, DocumentException, IOException 552 { 553 Collection elements = page.getElements(); 554 exportElements(elements); 555 556 if (progressMonitor != null) 557 { 558 progressMonitor.afterPageExport(); 559 } 560 } 561 562 563 protected void exportElements(Collection elements) throws DocumentException, IOException , JRException 564 { 565 if (elements != null && elements.size() > 0) 566 { 567 JRPrintElement element; 568 for(Iterator it = elements.iterator(); it.hasNext();) 569 { 570 element = (JRPrintElement)it.next(); 571 572 if (element instanceof JRPrintLine) 573 { 574 exportLine((JRPrintLine)element); 575 } 576 else if (element instanceof JRPrintRectangle) 577 { 578 exportRectangle((JRPrintRectangle)element); 579 } 580 else if (element instanceof JRPrintEllipse) 581 { 582 exportEllipse((JRPrintEllipse)element); 583 } 584 else if (element instanceof JRPrintImage) 585 { 586 exportImage((JRPrintImage)element); 587 } 588 else if (element instanceof JRPrintText) 589 { 590 exportText((JRPrintText)element); 591 } 592 else if (element instanceof JRPrintFrame) 593 { 594 exportFrame((JRPrintFrame) element); 595 } 596 } 597 } 598 } 599 600 601 604 protected void exportLine(JRPrintLine line) 605 { 606 if (line.getPen() != JRGraphicElement.PEN_NONE) 607 { 608 pdfContentByte.setRGBColorStroke( 609 line.getForecolor().getRed(), 610 line.getForecolor().getGreen(), 611 line.getForecolor().getBlue() 612 ); 613 614 switch (line.getPen()) 615 { 616 case JRGraphicElement.PEN_DOTTED : 617 { 618 pdfContentByte.setLineWidth(1f); 619 pdfContentByte.setLineDash(5f, 3f, 0f); 620 break; 621 } 622 case JRGraphicElement.PEN_4_POINT : 623 { 624 pdfContentByte.setLineWidth(4f); 625 pdfContentByte.setLineDash(0f); 626 break; 627 } 628 case JRGraphicElement.PEN_2_POINT : 629 { 630 pdfContentByte.setLineWidth(2f); 631 pdfContentByte.setLineDash(0f); 632 break; 633 } 634 case JRGraphicElement.PEN_NONE : 635 { 636 break; 638 } 639 case JRGraphicElement.PEN_THIN : 640 { 641 pdfContentByte.setLineWidth(0.5f); 642 pdfContentByte.setLineDash(0f); 643 break; 644 } 645 case JRGraphicElement.PEN_1_POINT : 646 default : 647 { 648 pdfContentByte.setLineWidth(1f); 649 pdfContentByte.setLineDash(0f); 650 break; 651 } 652 } 653 654 if (line.getDirection() == JRLine.DIRECTION_TOP_DOWN) 655 { 656 pdfContentByte.moveTo( 657 line.getX() + getOffsetX(), 658 jasperPrint.getPageHeight() - line.getY() - getOffsetY() 659 ); 660 pdfContentByte.lineTo( 661 line.getX() + getOffsetX() + line.getWidth() - 1, 662 jasperPrint.getPageHeight() - line.getY() - getOffsetY() - line.getHeight() + 1 663 ); 664 } 665 else 666 { 667 pdfContentByte.moveTo( 668 line.getX() + getOffsetX(), 669 jasperPrint.getPageHeight() - line.getY() - getOffsetY() - line.getHeight() + 1 670 ); 671 pdfContentByte.lineTo( 672 line.getX() + getOffsetX() + line.getWidth() - 1, 673 jasperPrint.getPageHeight() - line.getY() - getOffsetY() 674 ); 675 } 676 677 pdfContentByte.stroke(); 678 679 pdfContentByte.setLineDash(0f); 680 } 681 } 682 683 684 687 protected void exportRectangle(JRPrintRectangle rectangle) 688 { 689 pdfContentByte.setRGBColorStroke( 690 rectangle.getForecolor().getRed(), 691 rectangle.getForecolor().getGreen(), 692 rectangle.getForecolor().getBlue() 693 ); 694 pdfContentByte.setRGBColorFill( 695 rectangle.getBackcolor().getRed(), 696 rectangle.getBackcolor().getGreen(), 697 rectangle.getBackcolor().getBlue() 698 ); 699 700 float borderCorrection = prepareGraphicElement(rectangle); 701 702 if (rectangle.getMode() == JRElement.MODE_OPAQUE) 703 { 704 pdfContentByte.roundRectangle( 705 rectangle.getX() + getOffsetX() - borderCorrection, 706 jasperPrint.getPageHeight() - rectangle.getY() - getOffsetY() - rectangle.getHeight() - borderCorrection + 1, 707 rectangle.getWidth() + 2 * borderCorrection - 1, 708 rectangle.getHeight() + 2 * borderCorrection - 1, 709 rectangle.getRadius() 710 ); 711 712 if (rectangle.getPen() == JRGraphicElement.PEN_DOTTED) 713 { 714 pdfContentByte.fill(); 715 716 pdfContentByte.roundRectangle( 717 rectangle.getX() + getOffsetX(), 718 jasperPrint.getPageHeight() - rectangle.getY() - getOffsetY() - rectangle.getHeight() + 1, 719 rectangle.getWidth() - 1, 720 rectangle.getHeight() - 1, 721 rectangle.getRadius() 722 ); 723 pdfContentByte.stroke(); 724 } 725 else 726 { 727 pdfContentByte.fillStroke(); 728 } 729 } 730 else 731 { 732 if (rectangle.getPen() != JRGraphicElement.PEN_NONE) 733 { 734 pdfContentByte.roundRectangle( 735 rectangle.getX() + getOffsetX() - borderCorrection, 736 jasperPrint.getPageHeight() - rectangle.getY() - getOffsetY() - rectangle.getHeight() - borderCorrection + 1, 737 rectangle.getWidth() + 2 * borderCorrection - 1, 738 rectangle.getHeight() + 2 * borderCorrection - 1, 739 rectangle.getRadius() 740 ); 741 742 pdfContentByte.stroke(); 743 } 744 } 745 746 pdfContentByte.setLineDash(0f); 747 } 748 749 750 protected float prepareGraphicElement(JRPrintGraphicElement element) 751 { 752 float borderCorrection = 0f; 753 754 switch (element.getPen()) 755 { 756 case JRGraphicElement.PEN_DOTTED : 757 { 758 borderCorrection = element.getMode() == JRElement.MODE_OPAQUE ? 0.5f : 0f; 759 pdfContentByte.setLineWidth(1f); 760 pdfContentByte.setLineDash(5f, 3f, 0f); 761 break; 762 } 763 case JRGraphicElement.PEN_4_POINT : 764 { 765 borderCorrection = 0.5f; 766 pdfContentByte.setLineWidth(4f); 767 pdfContentByte.setLineDash(0f); 768 break; 769 } 770 case JRGraphicElement.PEN_2_POINT : 771 { 772 borderCorrection = 0.5f; 773 pdfContentByte.setLineWidth(2f); 774 pdfContentByte.setLineDash(0f); 775 break; 776 } 777 case JRGraphicElement.PEN_THIN : 778 { 779 borderCorrection = 0.25f; 780 pdfContentByte.setLineWidth(0.5f); 781 pdfContentByte.setLineDash(0f); 782 break; 783 } 784 case JRGraphicElement.PEN_NONE : 785 { 786 borderCorrection = 0.5f; 787 pdfContentByte.setLineWidth(0f); 788 pdfContentByte.setLineDash(0f); 789 790 pdfContentByte.setRGBColorStroke( 791 element.getBackcolor().getRed(), 792 element.getBackcolor().getGreen(), 793 element.getBackcolor().getBlue() 794 ); 795 796 break; 797 } 798 case JRGraphicElement.PEN_1_POINT : 799 default : 800 { 801 borderCorrection = 0f; 802 pdfContentByte.setLineWidth(1f); 803 pdfContentByte.setLineDash(0f); 804 break; 805 } 806 } 807 return borderCorrection; 808 } 809 810 811 814 protected void exportEllipse(JRPrintEllipse ellipse) 815 { 816 pdfContentByte.setRGBColorStroke( 817 ellipse.getForecolor().getRed(), 818 ellipse.getForecolor().getGreen(), 819 ellipse.getForecolor().getBlue() 820 ); 821 pdfContentByte.setRGBColorFill( 822 ellipse.getBackcolor().getRed(), 823 ellipse.getBackcolor().getGreen(), 824 ellipse.getBackcolor().getBlue() 825 ); 826 827 float borderCorrection = prepareGraphicElement(ellipse); 828 829 if (ellipse.getMode() == JRElement.MODE_OPAQUE) 830 { 831 pdfContentByte.ellipse( 832 ellipse.getX() + getOffsetX() - borderCorrection, 833 jasperPrint.getPageHeight() - ellipse.getY() - getOffsetY() - ellipse.getHeight() - borderCorrection + 1, 834 ellipse.getX() + getOffsetX() + ellipse.getWidth() + borderCorrection - 1, 835 jasperPrint.getPageHeight() - ellipse.getY() - getOffsetY() + borderCorrection 836 ); 837 838 if (ellipse.getPen() == JRGraphicElement.PEN_DOTTED) 839 { 840 pdfContentByte.fill(); 841 842 pdfContentByte.ellipse( 843 ellipse.getX() + getOffsetX(), 844 jasperPrint.getPageHeight() - ellipse.getY() - getOffsetY() - ellipse.getHeight() + 1, 845 ellipse.getX() + getOffsetX() + ellipse.getWidth() - 1, 846 jasperPrint.getPageHeight() - ellipse.getY() - getOffsetY() 847 ); 848 pdfContentByte.stroke(); 849 } 850 else 851 { 852 pdfContentByte.fillStroke(); 853 } 854 } 855 else 856 { 857 if (ellipse.getPen() != JRGraphicElement.PEN_NONE) 858 { 859 pdfContentByte.ellipse( 860 ellipse.getX() + getOffsetX() - borderCorrection, 861 jasperPrint.getPageHeight() - ellipse.getY() - getOffsetY() - ellipse.getHeight() - borderCorrection + 1, 862 ellipse.getX() + getOffsetX() + ellipse.getWidth() + borderCorrection - 1, 863 jasperPrint.getPageHeight() - ellipse.getY() - getOffsetY() + borderCorrection 864 ); 865 866 pdfContentByte.stroke(); 867 } 868 } 869 870 pdfContentByte.setLineDash(0f); 871 } 872 873 874 877 protected void exportImage(JRPrintImage printImage) throws DocumentException, IOException , JRException 878 { 879 pdfContentByte.setRGBColorFill( 880 printImage.getBackcolor().getRed(), 881 printImage.getBackcolor().getGreen(), 882 printImage.getBackcolor().getBlue() 883 ); 884 885 if (printImage.getMode() == JRElement.MODE_OPAQUE) 886 { 887 float borderCorrection = .5f; 888 889 pdfContentByte.setRGBColorStroke( 890 printImage.getBackcolor().getRed(), 891 printImage.getBackcolor().getGreen(), 892 printImage.getBackcolor().getBlue() 893 ); 894 pdfContentByte.setLineWidth(0.1f); 895 pdfContentByte.setLineDash(0f); 896 pdfContentByte.rectangle( 897 printImage.getX() + getOffsetX() - borderCorrection, 898 jasperPrint.getPageHeight() - printImage.getY() - getOffsetY() + borderCorrection, 899 printImage.getWidth() + 2 * borderCorrection - 1, 900 - printImage.getHeight() - 2 * borderCorrection + 1 901 ); 902 pdfContentByte.fillStroke(); 903 } 904 905 int topPadding = printImage.getTopPadding(); 906 int leftPadding = printImage.getLeftPadding(); 907 int bottomPadding = printImage.getBottomPadding(); 908 int rightPadding = printImage.getRightPadding(); 909 910 int availableImageWidth = printImage.getWidth() - leftPadding - rightPadding; 911 availableImageWidth = (availableImageWidth < 0)?0:availableImageWidth; 912 913 int availableImageHeight = printImage.getHeight() - topPadding - bottomPadding; 914 availableImageHeight = (availableImageHeight < 0)?0:availableImageHeight; 915 916 JRRenderable renderer = printImage.getRenderer(); 917 918 if ( 919 renderer != null && 920 availableImageWidth > 0 && 921 availableImageHeight > 0 922 ) 923 { 924 int xoffset = 0; 925 int yoffset = 0; 926 927 Chunk chunk = null; 928 929 float scaledWidth = availableImageWidth; 930 float scaledHeight = availableImageHeight; 931 932 if (renderer.getType() == JRRenderable.TYPE_IMAGE) 933 { 934 936 com.lowagie.text.Image image = null; 939 940 float xalignFactor = getXAlignFactor(printImage); 941 float yalignFactor = getYAlignFactor(printImage); 942 943 switch(printImage.getScaleImage()) 944 { 945 case JRImage.SCALE_IMAGE_CLIP : 946 { 947 int normalWidth = availableImageWidth; 948 int normalHeight = availableImageHeight; 949 950 Dimension2D dimension = renderer.getDimension(); 951 if (dimension != null) 952 { 953 normalWidth = (int)dimension.getWidth(); 954 normalHeight = (int)dimension.getHeight(); 955 } 956 957 xoffset = (int)(xalignFactor * (availableImageWidth - normalWidth)); 958 yoffset = (int)(yalignFactor * (availableImageHeight - normalHeight)); 959 960 int minWidth = Math.min(normalWidth, availableImageWidth); 961 int minHeight = Math.min(normalHeight, availableImageHeight); 962 963 BufferedImage bi = 964 new BufferedImage (minWidth, minHeight, BufferedImage.TYPE_INT_ARGB); 965 966 Graphics2D g = bi.createGraphics(); 967 if (printImage.getMode() == JRElement.MODE_OPAQUE) 968 { 969 g.setColor(printImage.getBackcolor()); 970 g.fillRect(0, 0, minWidth, minHeight); 971 } 972 renderer.render( 973 g, 974 new java.awt.Rectangle ( 975 (xoffset > 0 ? 0 : xoffset), 976 (yoffset > 0 ? 0 : yoffset), 977 normalWidth, 978 normalHeight 979 ) 980 ); 981 g.dispose(); 982 983 xoffset = (xoffset < 0 ? 0 : xoffset); 984 yoffset = (yoffset < 0 ? 0 : yoffset); 985 986 988 image = com.lowagie.text.Image.getInstance(bi, null); 990 991 break; 992 } 993 case JRImage.SCALE_IMAGE_FILL_FRAME : 994 { 995 if (loadedImagesMap.containsKey(renderer)) 996 { 997 image = (com.lowagie.text.Image)loadedImagesMap.get(renderer); 998 } 999 else 1000 { 1001 try 1002 { 1003 image = com.lowagie.text.Image.getInstance(renderer.getImageData()); 1004 imageTesterPdfContentByte.addImage(image, 10, 0, 0, 10, 0, 0); 1005 } 1006 catch(Exception e) 1007 { 1008 java.awt.Image awtImage = 1009 JRImageRenderer.getInstance( 1010 renderer.getImageData(), 1011 printImage.getOnErrorType() 1012 ).getImage(); 1013 image = com.lowagie.text.Image.getInstance(awtImage, null); 1014 } 1015 1016 loadedImagesMap.put(renderer, image); 1017 } 1018 1019 image.scaleAbsolute(availableImageWidth, availableImageHeight); 1020 break; 1021 } 1022 case JRImage.SCALE_IMAGE_RETAIN_SHAPE : 1023 default : 1024 { 1025 if (loadedImagesMap.containsKey(renderer)) 1026 { 1027 image = (com.lowagie.text.Image)loadedImagesMap.get(renderer); 1028 } 1029 else 1030 { 1031 try 1032 { 1033 image = com.lowagie.text.Image.getInstance(renderer.getImageData()); 1034 imageTesterPdfContentByte.addImage(image, 10, 0, 0, 10, 0, 0); 1035 } 1036 catch(Exception e) 1037 { 1038 java.awt.Image awtImage = 1039 JRImageRenderer.getInstance( 1040 renderer.getImageData(), 1041 printImage.getOnErrorType() 1042 ).getImage(); 1043 image = com.lowagie.text.Image.getInstance(awtImage, null); 1044 } 1045 1046 loadedImagesMap.put(renderer, image); 1047 } 1048 1049 image.scaleToFit(availableImageWidth, availableImageHeight); 1050 1051 xoffset = (int)(xalignFactor * (availableImageWidth - image.plainWidth())); 1052 yoffset = (int)(yalignFactor * (availableImageHeight - image.plainHeight())); 1053 1054 xoffset = (xoffset < 0 ? 0 : xoffset); 1055 yoffset = (yoffset < 0 ? 0 : yoffset); 1056 1057 break; 1058 } 1059 } 1060 1061 chunk = new Chunk(image, -0.5f, 0.5f); 1062 1063 scaledWidth = image.scaledWidth(); 1064 scaledHeight = image.scaledHeight(); 1065 } 1066 else 1067 { 1068 double normalWidth = availableImageWidth; 1069 double normalHeight = availableImageHeight; 1070 1071 Dimension2D dimension = renderer.getDimension(); 1072 if (dimension != null) 1073 { 1074 float xalignFactor = getXAlignFactor(printImage); 1075 float yalignFactor = getYAlignFactor(printImage); 1076 1077 switch (printImage.getScaleImage()) 1078 { 1079 case JRImage.SCALE_IMAGE_CLIP: 1080 { 1081 normalWidth = dimension.getWidth(); 1082 normalHeight = dimension.getHeight(); 1083 xoffset = (int) (xalignFactor * (availableImageWidth - normalWidth)); 1084 yoffset = (int) (yalignFactor * (availableImageHeight - normalHeight)); 1085 break; 1086 } 1087 case JRImage.SCALE_IMAGE_FILL_FRAME: 1088 { 1089 xoffset = 0; 1090 yoffset = 0; 1091 break; 1092 } 1093 case JRImage.SCALE_IMAGE_RETAIN_SHAPE: 1094 default: 1095 { 1096 normalWidth = dimension.getWidth(); 1097 normalHeight = dimension.getHeight(); 1098 double ratioX = availableImageWidth / normalWidth; 1099 double ratioY = availableImageHeight / normalHeight; 1100 double ratio = ratioX < ratioY ? ratioX : ratioY; 1101 normalWidth *= ratio; 1102 normalHeight *= ratio; 1103 xoffset = (int) (xalignFactor * (availableImageWidth - normalWidth)); 1104 yoffset = (int) (yalignFactor * (availableImageHeight - normalHeight)); 1105 break; 1106 } 1107 } 1108 } 1109 1110 PdfTemplate template = pdfContentByte.createTemplate(availableImageWidth, availableImageHeight); 1111 1112 Graphics2D g = forceSvgShapes 1113 ? template.createGraphicsShapes(availableImageWidth, availableImageHeight) 1114 : template.createGraphics(availableImageWidth, availableImageHeight, new LocalFontMapper()); 1115 1116 if (printImage.getMode() == JRElement.MODE_OPAQUE) 1117 { 1118 g.setColor(printImage.getBackcolor()); 1119 g.fillRect(0, 0, 1120 normalWidth <= availableImageWidth ? (int) normalWidth : availableImageWidth, 1121 normalHeight <= availableImageHeight ? (int) normalHeight : availableImageHeight); 1122 } 1123 1124 Rectangle2D rectangle = new Rectangle2D.Double ( 1125 (xoffset > 0 ? 0 : xoffset), 1126 (yoffset > 0 ? 0 : yoffset), 1127 normalWidth, 1128 normalHeight); 1129 1130 renderer.render(g, rectangle); 1131 g.dispose(); 1132 1133 xoffset = (xoffset < 0 ? 0 : xoffset); 1134 yoffset = (yoffset < 0 ? 0 : yoffset); 1135 1136 pdfContentByte.saveState(); 1137 pdfContentByte.addTemplate( 1138 template, 1139 printImage.getX() + getOffsetX() + xoffset, 1140 jasperPrint.getPageHeight() 1141 - printImage.getY() - getOffsetY() 1142 - availableImageHeight 1143 - yoffset 1144 ); 1145 pdfContentByte.restoreState(); 1146 1147 Image image = getPxImage(); 1148 image.scaleAbsolute(availableImageWidth, availableImageHeight); 1149 chunk = new Chunk(image, 0, 0); 1150 } 1151 1152 1160 1161 1162 setAnchor(chunk, printImage, printImage); 1163 setHyperlinkInfo(chunk, printImage); 1164 1165 ColumnText colText = new ColumnText(pdfContentByte); 1166 int upperY = jasperPrint.getPageHeight() - printImage.getY() - topPadding - getOffsetY() - yoffset; 1167 int lowerX = printImage.getX() + leftPadding + getOffsetX() + xoffset; 1168 colText.setSimpleColumn( 1169 new Phrase(chunk), 1170 lowerX, 1171 upperY - scaledHeight, 1172 lowerX + scaledWidth, 1173 upperY, 1174 scaledHeight, 1175 Element.ALIGN_LEFT 1176 ); 1177 1178 colText.go(); 1179 } 1180 1181 1182 if ( 1183 printImage.getTopBorder() == JRGraphicElement.PEN_NONE && 1184 printImage.getLeftBorder() == JRGraphicElement.PEN_NONE && 1185 printImage.getBottomBorder() == JRGraphicElement.PEN_NONE && 1186 printImage.getRightBorder() == JRGraphicElement.PEN_NONE 1187 ) 1188 { 1189 if (printImage.getPen() != JRGraphicElement.PEN_NONE) 1190 { 1191 exportBox(getBox(printImage), printImage); 1192 } 1193 } 1194 else 1195 { 1196 1197 exportBox( 1198 printImage, 1199 printImage 1200 ); 1201 } 1202 } 1203 1204 1205 private float getXAlignFactor(JRPrintImage printImage) 1206 { 1207 float xalignFactor = 0f; 1208 switch (printImage.getHorizontalAlignment()) 1209 { 1210 case JRAlignment.HORIZONTAL_ALIGN_RIGHT : 1211 { 1212 xalignFactor = 1f; 1213 break; 1214 } 1215 case JRAlignment.HORIZONTAL_ALIGN_CENTER : 1216 { 1217 xalignFactor = 0.5f; 1218 break; 1219 } 1220 case JRAlignment.HORIZONTAL_ALIGN_LEFT : 1221 default : 1222 { 1223 xalignFactor = 0f; 1224 break; 1225 } 1226 } 1227 return xalignFactor; 1228 } 1229 1230 1231 private float getYAlignFactor(JRPrintImage printImage) 1232 { 1233 float yalignFactor = 0f; 1234 switch (printImage.getVerticalAlignment()) 1235 { 1236 case JRAlignment.VERTICAL_ALIGN_BOTTOM : 1237 { 1238 yalignFactor = 1f; 1239 break; 1240 } 1241 case JRAlignment.VERTICAL_ALIGN_MIDDLE : 1242 { 1243 yalignFactor = 0.5f; 1244 break; 1245 } 1246 case JRAlignment.VERTICAL_ALIGN_TOP : 1247 default : 1248 { 1249 yalignFactor = 0f; 1250 break; 1251 } 1252 } 1253 return yalignFactor; 1254 } 1255 1256 1257 1260 protected void setHyperlinkInfo(Chunk chunk, JRPrintHyperlink link) 1261 { 1262 switch(link.getHyperlinkType()) 1263 { 1264 case JRHyperlink.HYPERLINK_TYPE_REFERENCE : 1265 { 1266 if (link.getHyperlinkReference() != null) 1267 { 1268 chunk.setAnchor(link.getHyperlinkReference()); 1269 } 1270 break; 1271 } 1272 case JRHyperlink.HYPERLINK_TYPE_LOCAL_ANCHOR : 1273 { 1274 if (link.getHyperlinkAnchor() != null) 1275 { 1276 chunk.setLocalGoto(link.getHyperlinkAnchor()); 1277 } 1278 break; 1279 } 1280 case JRHyperlink.HYPERLINK_TYPE_LOCAL_PAGE : 1281 { 1282 if (link.getHyperlinkPage() != null) 1283 { 1284 chunk.setLocalGoto(JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + link.getHyperlinkPage().toString()); 1285 } 1286 break; 1287 } 1288 case JRHyperlink.HYPERLINK_TYPE_REMOTE_ANCHOR : 1289 { 1290 if ( 1291 link.getHyperlinkReference() != null && 1292 link.getHyperlinkAnchor() != null 1293 ) 1294 { 1295 chunk.setRemoteGoto( 1296 link.getHyperlinkReference(), 1297 link.getHyperlinkAnchor() 1298 ); 1299 } 1300 break; 1301 } 1302 case JRHyperlink.HYPERLINK_TYPE_REMOTE_PAGE : 1303 { 1304 if ( 1305 link.getHyperlinkReference() != null && 1306 link.getHyperlinkPage() != null 1307 ) 1308 { 1309 chunk.setRemoteGoto( 1310 link.getHyperlinkReference(), 1311 link.getHyperlinkPage().intValue() 1312 ); 1313 } 1314 break; 1315 } 1316 case JRHyperlink.HYPERLINK_TYPE_CUSTOM : 1317 { 1318 if (hyperlinkProducerFactory != null) 1319 { 1320 String hyperlink = hyperlinkProducerFactory.produceHyperlink(link); 1321 if (hyperlink != null) 1322 { 1323 chunk.setAnchor(hyperlink); 1324 } 1325 } 1326 } 1327 case JRHyperlink.HYPERLINK_TYPE_NONE : 1328 default : 1329 { 1330 break; 1331 } 1332 } 1333 } 1334 1335 1336 1339 protected Phrase getPhrase(JRStyledText styledText, JRPrintText textElement) 1340 { 1341 Phrase phrase = new Phrase(); 1342 1343 String text = styledText.getText(); 1344 1345 int runLimit = 0; 1346 1347 AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator(); 1348 1349 while(runLimit < styledText.length() && (runLimit = iterator.getRunLimit()) <= styledText.length()) 1350 { 1351 Chunk chunk = getChunk(iterator.getAttributes(), text.substring(iterator.getIndex(), runLimit)); 1352 setAnchor(chunk, textElement, textElement); 1353 setHyperlinkInfo(chunk, textElement); 1354 phrase.add(chunk); 1355 1356 iterator.setIndex(runLimit); 1357 } 1358 1359 return phrase; 1360 } 1361 1362 1363 1366 protected Chunk getChunk(Map attributes, String text) 1367 { 1368 Font font = getFont(attributes); 1369 1370 Chunk chunk = new Chunk(text, font); 1371 1372 Color backcolor = (Color )attributes.get(TextAttribute.BACKGROUND); 1373 if (backcolor != null) 1374 { 1375 chunk.setBackground(backcolor); 1376 } 1377 1378 Object script = attributes.get(TextAttribute.SUPERSCRIPT); 1379 if (script != null) 1380 { 1381 if (TextAttribute.SUPERSCRIPT_SUPER.equals(script)) 1382 { 1383 chunk.setTextRise(font.leading(1f)/2); 1384 } 1385 else if (script != null && TextAttribute.SUPERSCRIPT_SUB.equals(script)) 1386 { 1387 chunk.setTextRise(-font.leading(1f)/2); 1388 } 1389 } 1390 1391 if (splitCharacter != null) 1392 { 1393 chunk.setSplitCharacter(splitCharacter); 1394 } 1395 1396 return chunk; 1397 } 1398 1399 1400 1403 protected Font getFont(Map attributes) 1404 { 1405 JRFont jrFont = new JRBaseFont(attributes); 1406 1407 Exception initialException = null; 1408 1409 Color forecolor = (Color )attributes.get(TextAttribute.FOREGROUND); 1410 1416 1417 Font font = null; 1418 PdfFont pdfFont = null; 1419 FontKey key = new FontKey(jrFont.getFontName(), jrFont.isBold(), jrFont.isItalic()); 1420 1421 if (fontMap != null && fontMap.containsKey(key)) 1422 { 1423 pdfFont = (PdfFont) fontMap.get(key); 1424 } 1425 else 1426 { 1427 pdfFont = new PdfFont(jrFont.getPdfFontName(), jrFont.getPdfEncoding(), jrFont.isPdfEmbedded()); 1428 } 1429 1430 try 1431 { 1432 font = FontFactory.getFont( 1433 pdfFont.getPdfFontName(), 1434 pdfFont.getPdfEncoding(), 1435 pdfFont.isPdfEmbedded(), 1436 jrFont.getFontSize(), 1437 (pdfFont.isPdfSimulatedBold() ? Font.BOLD : 0) 1438 | (pdfFont.isPdfSimulatedItalic() ? Font.ITALIC : 0) 1439 | (jrFont.isUnderline() ? Font.UNDERLINE : 0) 1440 | (jrFont.isStrikeThrough() ? Font.STRIKETHRU : 0), 1441 forecolor 1442 ); 1443 1444 if (font.getBaseFont() == null && font.family() == Font.UNDEFINED) 1446 { 1447 font = null; 1448 } 1449 } 1450 catch(Exception e) 1451 { 1452 initialException = e; 1453 } 1454 1455 if (font == null) 1456 { 1457 byte[] bytes = null; 1458 1459 try 1460 { 1461 bytes = JRLoader.loadBytesFromLocation(pdfFont.getPdfFontName(), classLoader, urlHandlerFactory); 1462 } 1463 catch(JRException e) 1464 { 1465 throw 1466 new JRRuntimeException( 1467 "Could not load the following font : " 1468 + "\npdfFontName : " + pdfFont.getPdfFontName() 1469 + "\npdfEncoding : " + pdfFont.getPdfEncoding() 1470 + "\nisPdfEmbedded : " + pdfFont.isPdfEmbedded(), 1471 initialException 1472 ); 1473 } 1474 1475 BaseFont baseFont = null; 1476 1477 try 1478 { 1479 baseFont = 1480 BaseFont.createFont( 1481 pdfFont.getPdfFontName(), 1482 pdfFont.getPdfEncoding(), 1483 pdfFont.isPdfEmbedded(), 1484 true, 1485 bytes, 1486 null 1487 ); 1488 } 1489 catch(DocumentException e) 1490 { 1491 throw new JRRuntimeException(e); 1492 } 1493 catch(IOException e) 1494 { 1495 throw new JRRuntimeException(e); 1496 } 1497 1498 font = 1499 new Font( 1500 baseFont, 1501 jrFont.getFontSize(), 1502 ((pdfFont.isPdfSimulatedBold()) ? Font.BOLD : 0) 1503 | ((pdfFont.isPdfSimulatedItalic()) ? Font.ITALIC : 0) 1504 | (jrFont.isUnderline() ? Font.UNDERLINE : 0) 1505 | (jrFont.isStrikeThrough() ? Font.STRIKETHRU : 0), 1506 forecolor 1507 ); 1508 } 1509 1510 return font; 1511 } 1512 1513 1514 1517 protected void exportText(JRPrintText text) throws DocumentException 1518 { 1519 JRStyledText styledText = getStyledText(text, false); 1520 1521 if (styledText == null) 1522 { 1523 return; 1524 } 1525 1526 int textLength = styledText.length(); 1527 1528 int x = text.getX() + getOffsetX(); 1529 int y = text.getY() + getOffsetY(); 1530 int width = text.getWidth(); 1531 int height = text.getHeight(); 1532 int topPadding = text.getTopPadding(); 1533 int leftPadding = text.getLeftPadding(); 1534 int bottomPadding = text.getBottomPadding(); 1535 int rightPadding = text.getRightPadding(); 1536 1537 int xFillCorrection = 0; 1538 int yFillCorrection = 0; 1539 1540 double angle = 0; 1541 1542 switch (text.getRotation()) 1543 { 1544 case JRTextElement.ROTATION_LEFT : 1545 { 1546 y = text.getY() + getOffsetY() + text.getHeight(); 1547 xFillCorrection = 1; 1548 width = text.getHeight(); 1549 height = text.getWidth(); 1550 int tmpPadding = topPadding; 1551 topPadding = leftPadding; 1552 leftPadding = bottomPadding; 1553 bottomPadding = rightPadding; 1554 rightPadding = tmpPadding; 1555 angle = Math.PI / 2; 1556 break; 1557 } 1558 case JRTextElement.ROTATION_RIGHT : 1559 { 1560 x = text.getX() + getOffsetX() + text.getWidth(); 1561 yFillCorrection = -1; 1562 width = text.getHeight(); 1563 height = text.getWidth(); 1564 int tmpPadding = topPadding; 1565 topPadding = rightPadding; 1566 rightPadding = bottomPadding; 1567 bottomPadding = leftPadding; 1568 leftPadding = tmpPadding; 1569 angle = - Math.PI / 2; 1570 break; 1571 } 1572 case JRTextElement.ROTATION_UPSIDE_DOWN : 1573 { 1574 x = text.getX() + getOffsetX() + text.getWidth(); 1575 y = text.getY() + getOffsetY() + text.getHeight(); 1576 int tmpPadding = topPadding; 1577 topPadding = bottomPadding; 1578 bottomPadding = tmpPadding; 1579 tmpPadding = leftPadding; 1580 leftPadding = rightPadding; 1581 rightPadding = tmpPadding; 1582 angle = Math.PI; 1583 break; 1584 } 1585 case JRTextElement.ROTATION_NONE : 1586 default : 1587 { 1588 } 1589 } 1590 1591 AffineTransform atrans = new AffineTransform (); 1592 atrans.rotate(angle, x, jasperPrint.getPageHeight() - y); 1593 pdfContentByte.transform(atrans); 1594 1595 if (text.getMode() == JRElement.MODE_OPAQUE) 1596 { 1597 Color backcolor = text.getBackcolor(); 1598 pdfContentByte.setRGBColorStroke( 1599 backcolor.getRed(), 1600 backcolor.getGreen(), 1601 backcolor.getBlue() 1602 ); 1603 pdfContentByte.setRGBColorFill( 1604 backcolor.getRed(), 1605 backcolor.getGreen(), 1606 backcolor.getBlue() 1607 ); 1608 pdfContentByte.setLineWidth(1f); 1609 pdfContentByte.setLineDash(0f); 1610 pdfContentByte.rectangle( 1611 x + xFillCorrection, 1612 jasperPrint.getPageHeight() - y + yFillCorrection, 1613 width - 1, 1614 - height + 1 1615 ); 1616 pdfContentByte.fillStroke(); 1617 } 1618 else 1619 { 1620 1636 } 1637 1638 if (textLength > 0) 1639 { 1640 int horizontalAlignment = Element.ALIGN_LEFT; 1641 switch (text.getHorizontalAlignment()) 1642 { 1643 case JRAlignment.HORIZONTAL_ALIGN_LEFT : 1644 { 1645 if (text.getRunDirection() == JRPrintText.RUN_DIRECTION_LTR) 1646 { 1647 horizontalAlignment = Element.ALIGN_LEFT; 1648 } 1649 else 1650 { 1651 horizontalAlignment = Element.ALIGN_RIGHT; 1652 } 1653 break; 1654 } 1655 case JRAlignment.HORIZONTAL_ALIGN_CENTER : 1656 { 1657 horizontalAlignment = Element.ALIGN_CENTER; 1658 break; 1659 } 1660 case JRAlignment.HORIZONTAL_ALIGN_RIGHT : 1661 { 1662 if (text.getRunDirection() == JRPrintText.RUN_DIRECTION_LTR) 1663 { 1664 horizontalAlignment = Element.ALIGN_RIGHT; 1665 } 1666 else 1667 { 1668 horizontalAlignment = Element.ALIGN_LEFT; 1669 } 1670 break; 1671 } 1672 case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED : 1673 { 1674 horizontalAlignment = Element.ALIGN_JUSTIFIED; 1675 break; 1676 } 1677 default : 1678 { 1679 horizontalAlignment = Element.ALIGN_LEFT; 1680 } 1681 } 1682 1683 float verticalOffset = 0f; 1684 switch (text.getVerticalAlignment()) 1685 { 1686 case JRAlignment.VERTICAL_ALIGN_TOP : 1687 { 1688 verticalOffset = 0f; 1689 break; 1690 } 1691 case JRAlignment.VERTICAL_ALIGN_MIDDLE : 1692 { 1693 verticalOffset = (height - topPadding - bottomPadding - text.getTextHeight()) / 2f; 1694 break; 1695 } 1696 case JRAlignment.VERTICAL_ALIGN_BOTTOM : 1697 { 1698 verticalOffset = height - topPadding - bottomPadding - text.getTextHeight(); 1699 break; 1700 } 1701 default : 1702 { 1703 verticalOffset = 0f; 1704 } 1705 } 1706 1707 ColumnText colText = new ColumnText(pdfContentByte); 1708 colText.setSimpleColumn( 1709 getPhrase(styledText, text), 1710 x + leftPadding, 1711 jasperPrint.getPageHeight() 1712 - y 1713 - topPadding 1714 - verticalOffset 1715 - text.getLeadingOffset(), 1716 x + width - rightPadding, 1718 jasperPrint.getPageHeight() 1719 - y 1720 - height 1721 + bottomPadding, 1722 0, horizontalAlignment 1724 ); 1725 1726 colText.setLeading(0, text.getLineSpacingFactor()); colText.setRunDirection( 1728 text.getRunDirection() == JRPrintText.RUN_DIRECTION_LTR 1729 ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_RTL 1730 ); 1731 1732 colText.go(); 1733 } 1734 1735 atrans = new AffineTransform (); 1736 atrans.rotate(-angle, x, jasperPrint.getPageHeight() - y); 1737 pdfContentByte.transform(atrans); 1738 1739 1740 exportBox( 1741 text, 1742 text 1743 ); 1744 } 1745 1746 1747 1750 protected void exportBox(JRBox box, JRPrintElement element) 1751 { 1752 if (box.getTopBorder() != JRGraphicElement.PEN_NONE) 1753 { 1754 float borderCorrection = prepareBorder(pdfContentByte, box.getTopBorder()); 1755 Color color = box.getTopBorderColor() == null ? element.getForecolor() : box.getTopBorderColor(); 1756 pdfContentByte.setRGBColorStroke( 1757 color.getRed(), 1758 color.getGreen(), 1759 color.getBlue() 1760 ); 1761 pdfContentByte.moveTo( 1762 element.getX() + getOffsetX() - borderCorrection, 1763 jasperPrint.getPageHeight() - element.getY() - getOffsetY() + borderCorrection 1764 ); 1765 pdfContentByte.lineTo( 1766 element.getX() + getOffsetX() + element.getWidth() - 1 + borderCorrection, 1767 jasperPrint.getPageHeight() - element.getY() - getOffsetY() + borderCorrection 1768 ); 1769 pdfContentByte.stroke(); 1770 } 1771 1772 if (box.getLeftBorder() != JRGraphicElement.PEN_NONE) 1773 { 1774 float borderCorrection = prepareBorder(pdfContentByte, box.getLeftBorder()); 1775 Color color = box.getLeftBorderColor() == null ? element.getForecolor() : box.getLeftBorderColor(); 1776 pdfContentByte.setRGBColorStroke( 1777 color.getRed(), 1778 color.getGreen(), 1779 color.getBlue() 1780 ); 1781 pdfContentByte.moveTo( 1782 element.getX() + getOffsetX() - borderCorrection, 1783 jasperPrint.getPageHeight() - element.getY() - getOffsetY() + borderCorrection 1784 ); 1785 pdfContentByte.lineTo( 1786 element.getX() + getOffsetX() - borderCorrection, 1787 jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + 1 - borderCorrection 1788 ); 1789 pdfContentByte.stroke(); 1790 } 1791 1792 if (box.getBottomBorder() != JRGraphicElement.PEN_NONE) 1793 { 1794 float borderCorrection = prepareBorder(pdfContentByte, box.getBottomBorder()); 1795 Color color = box.getBottomBorderColor() == null ? element.getForecolor() : box.getBottomBorderColor(); 1796 pdfContentByte.setRGBColorStroke( 1797 color.getRed(), 1798 color.getGreen(), 1799 color.getBlue() 1800 ); 1801 pdfContentByte.moveTo( 1802 element.getX() + getOffsetX() - borderCorrection, 1803 jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + 1 - borderCorrection 1804 ); 1805 pdfContentByte.lineTo( 1806 element.getX() + getOffsetX() + element.getWidth() - 1 + borderCorrection, 1807 jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + 1 - borderCorrection 1808 ); 1809 pdfContentByte.stroke(); 1810 } 1811 1812 if (box.getRightBorder() != JRGraphicElement.PEN_NONE) 1813 { 1814 float borderCorrection = prepareBorder(pdfContentByte, box.getRightBorder()); 1815 Color color = box.getRightBorderColor() == null ? element.getForecolor() : box.getRightBorderColor(); 1816 pdfContentByte.setRGBColorStroke( 1817 color.getRed(), 1818 color.getGreen(), 1819 color.getBlue() 1820 ); 1821 pdfContentByte.moveTo( 1822 element.getX() + getOffsetX() + element.getWidth() - 1 + borderCorrection, 1823 jasperPrint.getPageHeight() - element.getY() - getOffsetY() + borderCorrection 1824 ); 1825 pdfContentByte.lineTo( 1826 element.getX() + getOffsetX() + element.getWidth() - 1 + borderCorrection, 1827 jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + 1 - borderCorrection 1828 ); 1829 pdfContentByte.stroke(); 1830 } 1831 1832 pdfContentByte.setLineDash(0f); 1833 } 1834 1835 1836 1839 private static float prepareBorder(PdfContentByte pdfContentByte, byte border) 1840 { 1841 float borderCorrection = 0f; 1842 1843 switch (border) 1844 { 1845 case JRGraphicElement.PEN_DOTTED : 1846 { 1847 borderCorrection = 0f; 1848 pdfContentByte.setLineWidth(1f); 1849 pdfContentByte.setLineDash(5f, 3f, 0f); 1850 break; 1851 } 1852 case JRGraphicElement.PEN_4_POINT : 1853 { 1854 borderCorrection = .5f; 1855 pdfContentByte.setLineWidth(4f); 1856 pdfContentByte.setLineDash(0f); 1857 break; 1858 } 1859 case JRGraphicElement.PEN_2_POINT : 1860 { 1861 borderCorrection = .5f; 1862 pdfContentByte.setLineWidth(2f); 1863 pdfContentByte.setLineDash(0f); 1864 break; 1865 } 1866 case JRGraphicElement.PEN_THIN : 1867 { 1868 borderCorrection = 0.25f; 1869 pdfContentByte.setLineWidth(0.5f); 1870 pdfContentByte.setLineDash(0f); 1871 break; 1872 } 1873 case JRGraphicElement.PEN_NONE : 1874 { 1875 borderCorrection = 0.5f; 1876 pdfContentByte.setLineWidth(1f); 1877 pdfContentByte.setLineDash(0f); 1878 break; 1879 } 1880 case JRGraphicElement.PEN_1_POINT : 1881 default : 1882 { 1883 borderCorrection = 0f; 1884 pdfContentByte.setLineWidth(1f); 1885 pdfContentByte.setLineDash(0f); 1886 break; 1887 } 1888 } 1889 1890 return borderCorrection; 1891 } 1892 1893 1894 protected static synchronized void registerFonts () 1895 { 1896 if (!fontsRegistered) 1897 { 1898 List fontFiles = JRProperties.getProperties(JRProperties.PDF_FONT_FILES_PREFIX); 1899 if (!fontFiles.isEmpty()) 1900 { 1901 for (Iterator i = fontFiles.iterator(); i.hasNext();) 1902 { 1903 JRProperties.PropertySuffix font = (JRProperties.PropertySuffix) i.next(); 1904 String file = font.getValue(); 1905 if (file.toLowerCase().endsWith(".ttc")) 1906 { 1907 FontFactory.register(file); 1908 } 1909 else 1910 { 1911 String alias = font.getSuffix(); 1912 FontFactory.register(file, alias); 1913 } 1914 } 1915 } 1916 1917 List fontDirs = JRProperties.getProperties(JRProperties.PDF_FONT_DIRS_PREFIX); 1918 if (!fontDirs.isEmpty()) 1919 { 1920 for (Iterator i = fontDirs.iterator(); i.hasNext();) 1921 { 1922 JRProperties.PropertySuffix dir = (JRProperties.PropertySuffix) i.next(); 1923 FontFactory.registerDirectory(dir.getValue()); 1924 } 1925 } 1926 1927 fontsRegistered = true; 1928 } 1929 } 1930 1931 1932 static protected class Bookmark 1933 { 1934 final PdfOutline pdfOutline; 1935 final int level; 1936 1937 Bookmark(Bookmark parent, int x, int top, String title) 1938 { 1939 this(parent, new PdfDestination(PdfDestination.XYZ, x, top, 0), title); 1940 } 1941 1942 Bookmark(Bookmark parent, PdfDestination destination, String title) 1943 { 1944 this.pdfOutline = new PdfOutline(parent.pdfOutline, destination, title, false); 1945 this.level = parent.level + 1; 1946 } 1947 1948 Bookmark(PdfOutline pdfOutline, int level) 1949 { 1950 this.pdfOutline = pdfOutline; 1951 this.level = level; 1952 } 1953 } 1954 1955 static protected class BookmarkStack 1956 { 1957 LinkedList stack; 1958 1959 BookmarkStack() 1960 { 1961 stack = new LinkedList (); 1962 } 1963 1964 void push(Bookmark bookmark) 1965 { 1966 stack.add(bookmark); 1967 } 1968 1969 Bookmark pop() 1970 { 1971 return (Bookmark) stack.removeLast(); 1972 } 1973 1974 Bookmark peek() 1975 { 1976 return (Bookmark) stack.getLast(); 1977 } 1978 } 1979 1980 1981 protected void initBookmarks() 1982 { 1983 bookmarkStack = new BookmarkStack(); 1984 1985 int rootLevel = isModeBatch && isCreatingBatchModeBookmarks ? -1 : 0; 1986 Bookmark bookmark = new Bookmark(pdfContentByte.getRootOutline(), rootLevel); 1987 bookmarkStack.push(bookmark); 1988 } 1989 1990 1991 protected void addBookmark(int level, String title, int x, int y) 1992 { 1993 Bookmark parent = bookmarkStack.peek(); 1994 while(parent.level > level - 1) 1995 { 1996 bookmarkStack.pop(); 1997 parent = bookmarkStack.peek(); 1998 } 1999 2000 for (int i = parent.level + 1; i < level; ++i) 2001 { 2002 Bookmark emptyBookmark = new Bookmark(parent, parent.pdfOutline.getPdfDestination(), EMPTY_BOOKMARK_TITLE); 2003 bookmarkStack.push(emptyBookmark); 2004 parent = emptyBookmark; 2005 } 2006 2007 Bookmark bookmark = new Bookmark(parent, x, jasperPrint.getPageHeight() - y, title); 2008 bookmarkStack.push(bookmark); 2009 } 2010 2011 2012 protected void setAnchor(Chunk chunk, JRPrintAnchor anchor, JRPrintElement element) 2013 { 2014 String anchorName = anchor.getAnchorName(); 2015 if (anchorName != null) 2016 { 2017 chunk.setLocalDestination(anchorName); 2018 2019 if (anchor.getBookmarkLevel() != JRAnchor.NO_BOOKMARK) 2020 { 2021 addBookmark(anchor.getBookmarkLevel(), anchor.getAnchorName(), element.getX(), element.getY()); 2022 } 2023 } 2024 } 2025 2026 2027 protected void exportFrame(JRPrintFrame frame) throws DocumentException, IOException , JRException 2028 { 2029 if (frame.getMode() == JRElement.MODE_OPAQUE) 2030 { 2031 int x = frame.getX() + getOffsetX(); 2032 int y = frame.getY() + getOffsetY(); 2033 2034 Color backcolor = frame.getBackcolor(); 2035 pdfContentByte.setRGBColorStroke( 2036 backcolor.getRed(), 2037 backcolor.getGreen(), 2038 backcolor.getBlue() 2039 ); 2040 pdfContentByte.setRGBColorFill( 2041 backcolor.getRed(), 2042 backcolor.getGreen(), 2043 backcolor.getBlue() 2044 ); 2045 pdfContentByte.setLineWidth(1f); 2046 pdfContentByte.setLineDash(0f); 2047 pdfContentByte.rectangle( 2048 x, 2049 jasperPrint.getPageHeight() - y, 2050 frame.getWidth() - 1, 2051 - frame.getHeight() + 1 2052 ); 2053 pdfContentByte.fillStroke(); 2054 } 2055 2056 setFrameElementsOffset(frame, false); 2057 try 2058 { 2059 exportElements(frame.getElements()); 2060 } 2061 finally 2062 { 2063 restoreElementOffsets(); 2064 } 2065 2066 exportBox(frame, frame); 2067 } 2068 2069 2070 2073 public static class NullOutputStream extends OutputStream 2074 { 2075 public NullOutputStream() 2076 { 2077 } 2078 2079 public void write(int b) 2080 { 2081 } 2083 2084 public void write(byte[] b, int off, int len) 2085 { 2086 } 2088 2089 public void write(byte[] b) 2090 { 2091 } 2093 } 2094 2095 2096 2099 class LocalFontMapper implements FontMapper 2100 { 2101 public LocalFontMapper() 2102 { 2103 } 2104 2105 public BaseFont awtToPdf(java.awt.Font font) 2106 { 2107 return getFont(font.getAttributes()).getBaseFont(); 2108 } 2109 2110 public java.awt.Font pdfToAwt(BaseFont font, int size) 2111 { 2112 return null; 2113 } 2114 } 2115} 2116 | Popular Tags |