KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jasperreports > engine > export > JRPdfExporter


1 /*
2  * ============================================================================
3  * GNU Lesser General Public License
4  * ============================================================================
5  *
6  * JasperReports - Free Java report-generating library.
7  * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * JasperSoft Corporation
24  * 303 Second Street, Suite 450 North
25  * San Francisco, CA 94107
26  * http://www.jaspersoft.com
27  */

28
29 /*
30  * Contributors:
31  * Adrian Jackson - iapetus@users.sourceforge.net
32  * David Taylor - exodussystems@users.sourceforge.net
33  * Lars Kristensen - llk@users.sourceforge.net
34  * Ling Li - lonecatz@users.sourceforge.net
35  * Martin Clough - mtclough@users.sourceforge.net
36  */

37 package net.sf.jasperreports.engine.export;
38
39 import java.awt.Color JavaDoc;
40 import java.awt.Graphics2D JavaDoc;
41 import java.awt.font.TextAttribute JavaDoc;
42 import java.awt.geom.AffineTransform JavaDoc;
43 import java.awt.geom.Dimension2D JavaDoc;
44 import java.awt.geom.Rectangle2D JavaDoc;
45 import java.awt.image.BufferedImage JavaDoc;
46 import java.io.File JavaDoc;
47 import java.io.FileOutputStream JavaDoc;
48 import java.io.IOException JavaDoc;
49 import java.io.OutputStream JavaDoc;
50 import java.text.AttributedCharacterIterator JavaDoc;
51 import java.util.Collection JavaDoc;
52 import java.util.HashMap JavaDoc;
53 import java.util.Iterator JavaDoc;
54 import java.util.LinkedList JavaDoc;
55 import java.util.List JavaDoc;
56 import java.util.Map JavaDoc;
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 /**
113  * Exports a JasperReports document to PDF format. It has binary output type and exports the document to
114  * a free-form layout.
115  * <p>
116  * Since classic AWT fonts can be sometimes very different from PDF fonts, a font mapping feature was added.
117  * By using the {@link JRExporterParameter#FONT_MAP} parameter, a logical font like "sansserif" can be mapped
118  * to a system specific font, like "Helvetica-BoldOblique". PDF font mapping is a little more complicated, because
119  * for a logical font, PDF cand provide two or more fonts, from the same family but with different styles (like
120  * "Helvetica", "Helvetica-Bold", "Helvetica-BoldOblique"). So every key in the map is a simple bean containing
121  * font family, bold and italic flag, and every value is another bean containing the PDF font name, encoding and
122  * embedding flag.
123  * @see FontKey
124  * @see PdfFont
125  * @author Teodor Danciu (teodord@users.sourceforge.net)
126  * @version $Id: JRPdfExporter.java 1511 2006-11-29 19:17:00 +0200 (Wed, 29 Nov 2006) teodord $
127  */

128 public class JRPdfExporter extends JRAbstractExporter
129 {
130
131     /**
132      * Property that provides a default value for the
133      * {@link net.sf.jasperreports.engine.export.JRPdfExporterParameter#FORCE_SVG_SHAPES JRPdfExporterParameter.FORCE_SVG_SHAPES}
134      * PDF exporter parameter.
135      *
136      * @see net.sf.jasperreports.engine.export.JRPdfExporterParameter#FORCE_SVG_SHAPES
137      */

138     public static final String JavaDoc PDF_FORCE_SVG_SHAPES = JRProperties.PROPERTY_PREFIX + "export.pdf.force.svg.shapes";
139
140     private static final String JavaDoc EMPTY_BOOKMARK_TITLE = "";
141
142     /**
143      *
144      */

145     protected static final String JavaDoc JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_";
146
147     protected static boolean fontsRegistered = false;
148
149     /**
150      *
151      */

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     /**
163      *
164      */

165     protected boolean isCreatingBatchModeBookmarks = false;
166     protected boolean isCompressed = false;
167     protected boolean isEncrypted = false;
168     protected boolean is128BitKey = false;
169     protected String JavaDoc userPassword = null;
170     protected String JavaDoc ownerPassword = null;
171     protected int permissions = 0;
172     protected Character JavaDoc pdfVersion = null;
173
174     /**
175      *
176      */

177     protected Map JavaDoc loadedImagesMap = null;
178     protected Image JavaDoc pxImage = null;
179     
180     private BookmarkStack bookmarkStack = null;
181
182     private Map JavaDoc fontMap = null;
183     
184     private boolean forceSvgShapes = true;
185     private SplitCharacter splitCharacter;
186     protected JRHyperlinkProducerFactory hyperlinkProducerFactory;
187
188     private String JavaDoc pdfJavaScript;
189
190     /**
191      *
192      */

193     protected Image JavaDoc 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 JavaDoc e)
205             {
206                 throw new JRRuntimeException(e);
207             }
208         }
209
210         return pxImage;
211     }
212
213
214     /**
215      *
216      */

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 JavaDoc isCreatingBatchModeBookmarksParameter = (Boolean JavaDoc)parameters.get(JRPdfExporterParameter.IS_CREATING_BATCH_MODE_BOOKMARKS);
241             if(isCreatingBatchModeBookmarksParameter != null){
242                 isCreatingBatchModeBookmarks = isCreatingBatchModeBookmarksParameter.booleanValue();
243             }
244     
245             Boolean JavaDoc isCompressedParameter = (Boolean JavaDoc)parameters.get(JRPdfExporterParameter.IS_COMPRESSED);
246             if (isCompressedParameter != null)
247             {
248                 isCompressed = isCompressedParameter.booleanValue();
249             }
250             
251             Boolean JavaDoc isEncryptedParameter = (Boolean JavaDoc)parameters.get(JRPdfExporterParameter.IS_ENCRYPTED);
252             if (isEncryptedParameter != null)
253             {
254                 isEncrypted = isEncryptedParameter.booleanValue();
255             }
256             
257             Boolean JavaDoc is128BitKeyParameter = (Boolean JavaDoc)parameters.get(JRPdfExporterParameter.IS_128_BIT_KEY);
258             if (is128BitKeyParameter != null)
259             {
260                 is128BitKey = is128BitKeyParameter.booleanValue();
261             }
262             
263             userPassword = (String JavaDoc)parameters.get(JRPdfExporterParameter.USER_PASSWORD);
264             ownerPassword = (String JavaDoc)parameters.get(JRPdfExporterParameter.OWNER_PASSWORD);
265     
266             Integer JavaDoc permissionsParameter = (Integer JavaDoc)parameters.get(JRPdfExporterParameter.PERMISSIONS);
267             if (permissionsParameter != null)
268             {
269                 permissions = permissionsParameter.intValue();
270             }
271     
272             pdfVersion = (Character JavaDoc) parameters.get(JRPdfExporterParameter.PDF_VERSION);
273     
274             fontMap = (Map JavaDoc) parameters.get(JRExporterParameter.FONT_MAP);
275             
276             setForceSvgShapes();
277             setSplitCharacter();
278             setHyperlinkProducerFactory();
279
280             pdfJavaScript = (String JavaDoc)parameters.get(JRPdfExporterParameter.PDF_JAVASCRIPT);
281
282             OutputStream JavaDoc os = (OutputStream JavaDoc)parameters.get(JRExporterParameter.OUTPUT_STREAM);
283             if (os != null)
284             {
285                 exportReportToStream(os);
286             }
287             else
288             {
289                 File JavaDoc destFile = (File JavaDoc)parameters.get(JRExporterParameter.OUTPUT_FILE);
290                 if (destFile == null)
291                 {
292                     String JavaDoc fileName = (String JavaDoc)parameters.get(JRExporterParameter.OUTPUT_FILE_NAME);
293                     if (fileName != null)
294                     {
295                         destFile = new File JavaDoc(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 JavaDoc(destFile);
306                     exportReportToStream(os);
307                     os.flush();
308                 }
309                 catch (IOException JavaDoc 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 JavaDoc e)
322                         {
323                         }
324                     }
325                 }
326             }
327         }
328         finally
329         {
330             resetExportContext();
331         }
332     }
333
334
335     protected void setForceSvgShapes()
336     {
337         Boolean JavaDoc forceSvgShapesParam = (Boolean JavaDoc) 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 JavaDoc useFillSplitCharacterParam = (Boolean JavaDoc) 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     /**
376      *
377      */

378     protected void exportReportToStream(OutputStream JavaDoc os) throws JRException
379     {
380         //ByteArrayOutputStream baos = new ByteArrayOutputStream();
381

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, //jasperPrint.getPageWidth(),
394
10 //jasperPrint.getPageHeight()
395
)
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             // Add meta-data parameters to generated PDF document
420
// mtclough@users.sourceforge.net 2005-12-05
421
String JavaDoc title = (String JavaDoc)parameters.get(JRPdfExporterParameter.METADATA_TITLE);
422             if( title != null )
423                 document.addTitle(title);
424             
425             String JavaDoc author = (String JavaDoc)parameters.get(JRPdfExporterParameter.METADATA_AUTHOR);
426             if( author != null )
427                 document.addAuthor(author);
428             
429             String JavaDoc subject = (String JavaDoc)parameters.get(JRPdfExporterParameter.METADATA_SUBJECT);
430             if( subject != null )
431                 document.addSubject(subject);
432             
433             String JavaDoc keywords = (String JavaDoc)parameters.get(JRPdfExporterParameter.METADATA_KEYWORDS);
434             if( keywords != null )
435                 document.addKeywords(keywords);
436             
437             String JavaDoc creator = (String JavaDoc)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() // discard the output
456
);
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 JavaDoc();
466                 document.setPageSize(new Rectangle(jasperPrint.getPageWidth(), jasperPrint.getPageHeight()));
467                 
468                 List JavaDoc pages = jasperPrint.getPages();
469                 if (pages != null && pages.size() > 0)
470                 {
471                     if (isModeBatch)
472                     {
473                         document.newPage();
474                         
475                         if( isCreatingBatchModeBookmarks ){
476                             //add a new level to our outline for this report
477
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);//PdfContentByte.LINE_CAP_PROJECTING_SQUARE since iText 1.02b
501

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 JavaDoc 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         //return os.toByteArray();
545
}
546
547
548     /**
549      *
550      */

551     protected void exportPage(JRPrintPage page) throws JRException, DocumentException, IOException JavaDoc
552     {
553         Collection JavaDoc elements = page.getElements();
554         exportElements(elements);
555         
556         if (progressMonitor != null)
557         {
558             progressMonitor.afterPageExport();
559         }
560     }
561
562
563     protected void exportElements(Collection JavaDoc elements) throws DocumentException, IOException JavaDoc, JRException
564     {
565         if (elements != null && elements.size() > 0)
566         {
567             JRPrintElement element;
568             for(Iterator JavaDoc 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     /**
602      *
603      */

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                     //never reached due to the initial if statement
637
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     /**
685      *
686      */

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()