KickJava   Java API By Example, From Geeks To Geeks.

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


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  * Matt Thompson - mthomp1234@users.sourceforge.net
32  */

33 package net.sf.jasperreports.engine.export;
34
35 import java.awt.Color JavaDoc;
36 import java.awt.Graphics2D JavaDoc;
37 import java.awt.Rectangle JavaDoc;
38 import java.awt.font.TextAttribute JavaDoc;
39 import java.awt.geom.Dimension2D JavaDoc;
40 import java.awt.image.BufferedImage JavaDoc;
41 import java.io.BufferedWriter JavaDoc;
42 import java.io.ByteArrayInputStream JavaDoc;
43 import java.io.File JavaDoc;
44 import java.io.FileOutputStream JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.io.OutputStream JavaDoc;
47 import java.io.OutputStreamWriter JavaDoc;
48 import java.io.StringWriter JavaDoc;
49 import java.io.Writer JavaDoc;
50 import java.text.AttributedCharacterIterator JavaDoc;
51 import java.util.ArrayList JavaDoc;
52 import java.util.Collection JavaDoc;
53 import java.util.Iterator JavaDoc;
54 import java.util.List JavaDoc;
55 import java.util.Map JavaDoc;
56
57 import net.sf.jasperreports.engine.JRAbstractExporter;
58 import net.sf.jasperreports.engine.JRAlignment;
59 import net.sf.jasperreports.engine.JRBox;
60 import net.sf.jasperreports.engine.JRElement;
61 import net.sf.jasperreports.engine.JRException;
62 import net.sf.jasperreports.engine.JRExporterParameter;
63 import net.sf.jasperreports.engine.JRFont;
64 import net.sf.jasperreports.engine.JRGraphicElement;
65 import net.sf.jasperreports.engine.JRImage;
66 import net.sf.jasperreports.engine.JRLine;
67 import net.sf.jasperreports.engine.JRPrintElement;
68 import net.sf.jasperreports.engine.JRPrintEllipse;
69 import net.sf.jasperreports.engine.JRPrintFrame;
70 import net.sf.jasperreports.engine.JRPrintGraphicElement;
71 import net.sf.jasperreports.engine.JRPrintImage;
72 import net.sf.jasperreports.engine.JRPrintLine;
73 import net.sf.jasperreports.engine.JRPrintPage;
74 import net.sf.jasperreports.engine.JRPrintRectangle;
75 import net.sf.jasperreports.engine.JRPrintText;
76 import net.sf.jasperreports.engine.JRRenderable;
77 import net.sf.jasperreports.engine.JRReport;
78 import net.sf.jasperreports.engine.JasperPrint;
79 import net.sf.jasperreports.engine.base.JRBaseFont;
80 import net.sf.jasperreports.engine.base.JRBasePrintText;
81 import net.sf.jasperreports.engine.util.JRImageLoader;
82 import net.sf.jasperreports.engine.util.JRStyledText;
83
84 /**
85  * Exports a JasperReports document to RTF format. It has binary output type and exports the document to
86  * a free-form layout. It uses the RTF Specification 1.6 (compatible with MS Word 6.0, 2003 and XP).
87  * <p>
88  * Since classic AWT fonts can be sometimes very different from system fonts (which are used by RTF viewers),
89  * a font mapping feature was added. By using the {@link JRExporterParameter#FONT_MAP} parameter, a logical
90  * font like "sansserif" can be mapped to a system specific font, like "Comic Sans MS". Both map keys and values are strings.
91  * @author Flavius Sana (flavius_sana@users.sourceforge.net)
92  * @version $Id: JRRtfExporter.java 1527 2006-12-15 11:31:36 +0200 (Fri, 15 Dec 2006) lucianc $
93  */

94 public class JRRtfExporter extends JRAbstractExporter
95 {
96     protected JRExportProgressMonitor progressMonitor = null;
97     
98     protected Writer JavaDoc writer = null;
99     protected File JavaDoc destFile = null;
100     
101     protected int reportIndex = 0;
102     
103     // temporaray list of fonts and colors to be
104
// added to the header or the document
105
private StringBuffer JavaDoc colorBuffer = null;
106     private StringBuffer JavaDoc fontBuffer = null;
107     protected List JavaDoc colors = null;
108     protected List JavaDoc fonts = null;
109
110     // z order of the graphical objects in .rtf file
111
private int zorder = 1;
112     
113     // indicate that report containts Unicode characters with code > 127
114
private boolean isUnicode = false;
115     
116     private Map JavaDoc fontMap = null;
117     
118     
119     /**
120      * Export report in .rtf format
121      */

122     public void exportReport() throws JRException
123     {
124         progressMonitor = (JRExportProgressMonitor)parameters.get(JRExporterParameter.PROGRESS_MONITOR);
125         
126
127         try
128         {
129             /* */
130             setExportContext();
131     
132             /* */
133             setInput();
134
135             if (!isModeBatch) {
136                 setPageRange();
137             }
138
139             fonts = new ArrayList JavaDoc();
140             fontBuffer = new StringBuffer JavaDoc();
141             colors = new ArrayList JavaDoc();
142             colors.add(null);
143             colorBuffer = new StringBuffer JavaDoc(";");
144             
145             fontMap = (Map JavaDoc) parameters.get(JRExporterParameter.FONT_MAP);
146             
147             StringBuffer JavaDoc sb = (StringBuffer JavaDoc)parameters.get(JRExporterParameter.OUTPUT_STRING_BUFFER);
148             if (sb != null) {
149                 StringBuffer JavaDoc buffer = exportReportToBuffer();
150                 sb.append(buffer.toString());
151             }
152             else {
153                 Writer JavaDoc outWriter = (Writer JavaDoc)parameters.get(JRExporterParameter.OUTPUT_WRITER);
154                 if (outWriter != null) {
155                     try {
156                         writer = outWriter;
157                         
158                         // export report
159
exportReportToStream();
160                     }
161                     catch (IOException JavaDoc ex) {
162                         throw new JRException("Error writing to writer : " + jasperPrint.getName(), ex);
163                     }
164                 }
165                 else {
166                     OutputStream JavaDoc os = (OutputStream JavaDoc)parameters.get(JRExporterParameter.OUTPUT_STREAM);
167                     if(os != null) {
168                         try {
169                             writer = new OutputStreamWriter JavaDoc(os);
170                             
171                             // export report
172
exportReportToStream();
173                         }
174                         catch (Exception JavaDoc ex) {
175                             throw new JRException("Error writing to output stream : " + jasperPrint.getName(), ex);
176                         }
177                     }
178                     else {
179                         destFile = (File JavaDoc)parameters.get(JRExporterParameter.OUTPUT_FILE);
180                         if (destFile == null) {
181                             String JavaDoc fileName = (String JavaDoc)parameters.get(JRExporterParameter.OUTPUT_FILE_NAME);
182                             if (fileName != null) {
183                                 destFile = new File JavaDoc(fileName);
184                             }
185                             else {
186                                 throw new JRException("No output specified for the exporter");
187                             }
188                         }
189                         
190                         // export report
191
exportReportToFile();
192                     }
193                 }
194             }
195         }
196         finally
197         {
198             resetExportContext();
199         }
200     }
201     
202     
203     /**
204      * Export report in .rtf format
205      * @return report in .rtf format in a StringBuffer object
206      */

207     protected StringBuffer JavaDoc exportReportToBuffer() throws JRException{
208         StringWriter JavaDoc buffer = new StringWriter JavaDoc();
209         writer = buffer;
210         try {
211             exportReportToStream();
212         }
213         catch (IOException JavaDoc ex) {
214             throw new JRException("Error while exporting report to the buffer");
215         }
216         
217         return buffer.getBuffer();
218     }
219     
220     
221     /**
222      * Export report in .rtf format to a stream
223      * @throws JRException
224      * @throws IOException
225      */

226     protected void exportReportToStream() throws JRException, IOException JavaDoc {
227         
228         // create the header of the rtf file
229
writer.write("{\\rtf1\\ansi\\deff0\n");
230         // create font and color tables
231
createColorAndFontEntries();
232         writer.write("{\\fonttbl ");
233         writer.write(fontBuffer.toString());
234         writer.write("}\n");
235         
236         writer.write("{\\colortbl ");
237         writer.write(colorBuffer.toString());
238         writer.write("}\n");
239         
240         
241         for(reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++ ){
242             jasperPrint = (JasperPrint)jasperPrintList.get(reportIndex);
243             
244             List JavaDoc pages = jasperPrint.getPages();
245             if (pages != null && pages.size() > 0){
246                 if (isModeBatch)
247                 {
248                     startPageIndex = 0;
249                     endPageIndex = pages.size() - 1;
250                 }
251                 JRPrintPage page = null;
252                 
253                 writer.write("{\\info{\\nofpages");
254                 writer.write(String.valueOf(pages.size()));
255                 writer.write("}}\n");
256                 
257                 writer.write("\\viewkind1\\paperw");
258                 writer.write(String.valueOf(twip(jasperPrint.getPageWidth())));
259                 writer.write("\\paperh");
260                 writer.write(String.valueOf(twip(jasperPrint.getPageHeight())));
261                 
262                 writer.write("\\marglsxn0\\margrsxn0\\margtsxn0\\margbsxn0");
263                 
264                 if (jasperPrint.getOrientation() == JRReport.ORIENTATION_LANDSCAPE) {
265                     writer.write("\\lndscpsxn");
266                 }
267                 
268                 
269                 for (int pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++) {
270                     writer.write("\n");
271                     if(Thread.currentThread().isInterrupted()){
272                         throw new JRException("Current thread intrerrupted");
273                     }
274                     
275                     page = (JRPrintPage)pages.get(pageIndex);
276                     
277                     boolean lastPageFlag = false;
278                     if(pageIndex == endPageIndex && reportIndex == (jasperPrintList.size() - 1)){
279                         lastPageFlag = true;
280                     }
281                     exportPage(page, lastPageFlag);
282                 }
283             }
284         }
285         writer.write("}\n");
286         writer.flush();
287     }
288     
289     
290     /**
291      * Export report to a file in the .rtf format
292      */

293     protected void exportReportToFile() throws JRException {
294         try {
295             OutputStream JavaDoc fileOutputStream = new FileOutputStream JavaDoc(destFile);
296             writer = new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(fileOutputStream));
297             exportReportToStream();
298         }
299         catch (IOException JavaDoc ex) {
300             throw new JRException("Error writing to the file : " + destFile, ex);
301         }
302         finally {
303             if(writer != null) {
304                 try {
305                     writer.close();
306                 }
307                 catch(IOException JavaDoc ex) {
308                     
309                 }
310             }
311         }
312     }
313     
314     
315     /**
316      * Create color and font entries for the header of .rtf file.
317      * Each color is represented by values of the red,
318      * green and blue components.
319      * @throws JRException
320      */

321     protected void createColorAndFontEntries() throws JRException {
322         for(reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++ ){
323             jasperPrint = (JasperPrint)jasperPrintList.get(reportIndex);
324
325             getFontIndex(new JRBasePrintText(jasperPrint.getDefaultStyleProvider()));
326             
327             List JavaDoc pages = jasperPrint.getPages();
328             if (pages != null && pages.size() > 0) {
329                 if (isModeBatch) {
330                     startPageIndex = 0;
331                     endPageIndex = pages.size() - 1;
332                 }
333
334                 for (int pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++) {
335                     if (Thread.currentThread().isInterrupted()) {
336                         throw new JRException("Current thread interrupted");
337                     }
338                     JRPrintPage page = (JRPrintPage)pages.get(pageIndex);
339                     JRPrintElement element = null;
340                     Collection JavaDoc elements = page.getElements();
341                     if (elements != null && elements.size() > 0)
342                     {
343                         for (Iterator JavaDoc it = elements.iterator(); it.hasNext();)
344                         {
345                             element = (JRPrintElement) it.next();
346                             getColorIndex(element.getForecolor());
347                             getColorIndex(element.getBackcolor());
348
349                             if (element instanceof JRPrintText)
350                             {
351                                 JRPrintText text = (JRPrintText)element;
352
353                                 // create color indices for box border color
354
getColorIndex(text.getBorderColor());
355                                 getColorIndex(text.getTopBorderColor());
356                                 getColorIndex(text.getBottomBorderColor());
357                                 getColorIndex(text.getLeftBorderColor());
358                                 getColorIndex(text.getRightBorderColor());
359
360                                 for(int i = 0; i < text.getText().length(); i++ ){
361                                     if((text.getText().charAt(i)) > 127){
362                                         isUnicode = true;
363                                         break;
364                                     }
365                                 }
366
367                                 int runLimit = 0;
368                                 JRStyledText styledText = getStyledText((JRPrintText)element);
369                                 AttributedCharacterIterator JavaDoc iterator = styledText.getAttributedString().getIterator();
370                                 while (runLimit < styledText.length()
371                                         && (runLimit = iterator.getRunLimit()) <= styledText.length())
372                                 {
373                                     Map JavaDoc styledTextAttributes = iterator.getAttributes();
374
375                                     getFontIndex(new JRBaseFont(styledTextAttributes));
376
377                                     getColorIndex((Color JavaDoc)styledTextAttributes.get(TextAttribute.FOREGROUND));
378                                     getColorIndex((Color JavaDoc)styledTextAttributes.get(TextAttribute.BACKGROUND));
379
380                                     iterator.setIndex(runLimit);
381                                 }
382
383                                 getFontIndex((JRPrintText)element);
384                             }
385                         }
386                     }
387                 }
388             }
389         }
390     }
391     
392     
393     /**
394      * Return color index from header of the .rtf file. If a color is not
395      * found is automatically added to the header of the rtf file. The
396      * method is called first when the header of the .rtf file is constructed
397      * and when a componenent needs a color for foreground or background
398      * @param color Color for which the index is required.
399      * @return index of the color from .rtf file header
400      */

401     private int getColorIndex(Color JavaDoc color)
402     {
403         int colorNdx = colors.indexOf(color);
404         if (colorNdx < 0)
405         {
406             colorNdx = colors.size();
407             colors.add(color);
408             colorBuffer.append("\\red").append(color.getRed())
409                     .append("\\green").append(color.getGreen())
410                     .append("\\blue").append(color.getBlue())
411                     .append(";");
412         }
413         return colorNdx;
414     }
415     
416     
417     /**
418      * Return font index from the header of the .rtf file. The method is
419      * called first when the header of the .rtf document is constructed and when a
420      * text component needs font informations.
421      * @param font the font for which the index is required
422      * @return index of the font from .rtf file header
423      */

424     private int getFontIndex(JRFont font)
425     {
426         String JavaDoc fontName = font.getFontName();
427         if(fontMap != null && fontMap.containsKey(fontName)){
428             fontName = (String JavaDoc)fontMap.get(fontName);
429         }
430         
431         int fontIndex = fonts.indexOf(fontName);
432         
433         if(fontIndex < 0) {
434             fontIndex = fonts.size();
435             fonts.add(fontName);
436             fontBuffer.append("{\\f").append(fontIndex).append("\\fnil ").append(fontName).append(";}");
437         }
438         
439         return fontIndex;
440     }
441     
442     /**
443      * Convert a int value from points to twips (multiply with 20)
444      * @param points value that needs to be converted
445      * @return converted value in twips
446      */

447     private int twip(int points) {
448         return points * 20;
449     }
450     
451     
452     /**
453      * Convert a float value to twips (multiply with 20)
454      * @param points value that need to be converted
455      * @return converted value in twips
456      */

457     private int twip(float points) {
458         return (int)(points * 20);
459     }
460     
461     
462     /**
463      * Exports a report page
464      * @param page Page that will be exported
465      * @throws JRException
466      */

467     protected void exportPage(JRPrintPage page, boolean lastPage) throws JRException, IOException JavaDoc
468     {
469         exportElements(page.getElements());
470         
471         if(lastPage == false){
472             if(isUnicode){
473                 writer.write("{\\pard\\pagebb\\par}\n" );
474             }
475             else {
476                 writer.write("\\page\n");
477             }
478             
479         }
480     }
481     
482     /**
483      * Add a graphic element to the .rtf document
484      * @param type Type of the graphic element
485      * @param x x axis position of the graphic element
486      * @param y y axis position of the graphic
487      * @param w width of the graphic element
488      * @param h height of the graphic element
489      * @throws IOException
490      */

491     private void startGraphic(String JavaDoc type, int x, int y, int w, int h) throws IOException JavaDoc {
492         writer.write("{\\*\\do\\dobxpage\\dobypage\\dodhgt");
493         writer.write(String.valueOf(zorder++));
494         
495         writer.write("\\");
496         writer.write(type);
497         
498         writer.write("\\dpx");
499         writer.write(String.valueOf(x));
500         writer.write("\\dpy");
501         writer.write(String.valueOf(y));
502         
503         writer.write("\\dpxsize");
504         writer.write(String.valueOf(w));
505         writer.write("\\dpysize");
506         writer.write(String.valueOf(h));
507     }
508     
509     /**
510      * Add document control words that marks the end of a graphic element
511      * @param element Graphic element
512      * @throws IOException
513      */

514     private void finishGraphic(JRPrintGraphicElement element) throws IOException JavaDoc {
515         int mode = 0;
516         if(element.getMode() == JRElement.MODE_OPAQUE) {
517             mode = 1;
518         }
519         
520         finishGraphic( element.getPen(),
521                     element.getForecolor(),
522                     element.getBackcolor(),
523                     mode );
524     }
525     
526     /**
527      * Add document control words that marks the end of a graphic element
528      * @param pen pen dimension
529      * @param fg foreground color
530      * @param bg background color
531      * @param fillPattern fill pattern
532      * @throws IOException
533      */

534     private void finishGraphic(byte pen, Color JavaDoc fg, Color JavaDoc bg, int fillPattern) throws IOException JavaDoc {
535         switch(pen) {
536             case JRGraphicElement.PEN_THIN:
537                 writer.write("\\dplinew10");
538                 break;
539             case JRGraphicElement.PEN_1_POINT:
540                 writer.write("\\dplinew20");
541                 break;
542             case JRGraphicElement.PEN_2_POINT:
543                 writer.write("\\dplinew40");
544                 break;
545             case JRGraphicElement.PEN_4_POINT:
546                 writer.write("\\dplinew80");
547                 break;
548             case JRGraphicElement.PEN_DOTTED:
549                 writer.write("\\dplinedash");
550                 break;
551             case JRGraphicElement.PEN_NONE:
552                 writer.write("\\dplinehollow");
553                 break;
554             default:
555                 writer.write("\\dplinew20");
556                 break;
557         }
558         
559         writer.write("\\dplinecor");
560         writer.write(String.valueOf(fg.getRed()));
561         writer.write("\\dplinecob");
562         writer.write(String.valueOf(fg.getBlue()));
563         writer.write("\\dplinecog");
564         writer.write(String.valueOf(fg.getGreen()));
565         
566         writer.write("\\dpfillfgcr");
567         writer.write(String.valueOf(fg.getRed()));
568         writer.write("\\dplinefgcb");
569         writer.write(String.valueOf(fg.getBlue()));
570         writer.write("\\dpfillfgcg");
571         writer.write(String.valueOf(fg.getGreen()));
572         
573         writer.write("\\dpfillbgcr");
574         writer.write(String.valueOf(bg.getRed()));
575         writer.write("\\dpfillbgcg");
576         writer.write(String.valueOf(bg.getGreen()));
577         writer.write("\\dpfillbgcb");
578         writer.write(String.valueOf(bg.getBlue()));
579         
580         writer.write("\\dpfillpat");
581         writer.write(String.valueOf(fillPattern));
582         writer.write("}\n");
583     }
584
585     
586     
587     /**
588      * Get border adjustment for graphic elements depending on pen width used
589      * @param pen
590      */

591     protected int getAdjustment(byte pen)
592     {
593         switch (pen)
594         {
595             case JRGraphicElement.PEN_THIN:
596                 return 0;
597             case JRGraphicElement.PEN_1_POINT:
598                 return 10;
599             case JRGraphicElement.PEN_2_POINT:
600                 return 20;
601             case JRGraphicElement.PEN_4_POINT:
602                 return 40;
603             case JRGraphicElement.PEN_DOTTED:
604                 return 0;
605             case JRGraphicElement.PEN_NONE:
606                 return 0;
607             default:
608                 return 0;
609         }
610     }
611     
612     
613     /**
614      * Draw a line object
615      * @param line JasperReports line object - JRPrintLine
616      * @throws IOException
617      */

618     protected void exportLine(JRPrintLine line) throws IOException JavaDoc {
619         int x = twip(line.getX() + getOffsetX());
620         int y = twip(line.getY() + getOffsetY());
621         int h = twip(line.getHeight());
622         int w = twip(line.getWidth());
623
624         if (w <= 20 || h <= 20)
625         {
626             if (w > 20)
627             {
628                 h = 0;
629             }
630             else
631             {
632                 w = 0;
633             }
634         }
635
636         startGraphic("dpline", x, y, w, h);
637
638         if (line.getDirection() == JRLine.DIRECTION_TOP_DOWN)
639         {
640             writer.write("\\dpptx");
641             writer.write(String.valueOf(x));
642             writer.write("\\dppty");
643             writer.write(String.valueOf(y));
644             writer.write("\\dpptx");
645             writer.write(String.valueOf(x + w));
646             writer.write("\\dppty");
647             writer.write(String.valueOf(y + h));
648         }
649         else
650         {
651             writer.write("\\dpptx");
652             writer.write(String.valueOf(x));
653             writer.write("\\dppty");
654             writer.write(String.valueOf(y + h));
655             writer.write("\\dpptx");
656             writer.write(String.valueOf(x + w));
657             writer.write("\\dppty");
658             writer.write(String.valueOf(y));
659         }
660
661         finishGraphic(line);
662     }
663     
664     
665     /**
666      * Draw a rectangle
667      * @param rect JasperReports rectangle object (JRPrintRectangle)
668      */

669     protected void exportRectangle(JRPrintRectangle rect) throws IOException JavaDoc {
670         startGraphic("dprect" + (rect.getRadius() > 0 ? "\\dproundr" : ""),
671                 twip(rect.getX() + getOffsetX()),
672                 twip(rect.getY() + getOffsetY()),
673                 twip(rect.getWidth()),
674                 twip(rect.getHeight())
675                 );
676         finishGraphic(rect);
677     }
678     
679     
680     /**
681      * Draw a ellipse object
682      * @param ellipse JasperReports ellipse object (JRPrintElipse)
683      */

684     protected void exportEllipse(JRPrintEllipse ellipse) throws IOException JavaDoc {
685         startGraphic(
686             "dpellipse",
687             twip(ellipse.getX() + getOffsetX()),
688             twip(ellipse.getY() + getOffsetY()),
689             twip(ellipse.getWidth()),
690             twip(ellipse.getHeight())
691         );
692         finishGraphic(ellipse);
693     }
694
695     
696     /**
697      * Draw a text box
698      * @param text JasperReports text object (JRPrintText)
699      * @throws JRException
700      */

701     protected void exportText(JRPrintText text) throws IOException JavaDoc, JRException {
702         
703         
704         // use styled text
705
JRStyledText styledText = getStyledText(text);
706         if (styledText == null)
707         {
708             return;
709         }
710
711         int x = twip(text.getX() + getOffsetX());
712         int y = twip(text.getY() + getOffsetY());
713
714         int width = twip(text.getWidth());
715         int height = twip(text.getHeight());
716
717         int textBoxAdjustment = 20;
718         
719         int textHeight = twip(text.getTextHeight());
720         
721         if(textHeight <= 0) {
722             if(height <= 0 ){
723                 throw new JRException("Invalid text height");
724             }
725             textHeight = height;
726         }
727         
728         // padding for the text
729
int topPadding = twip(text.getTopPadding());
730         int leftPadding = twip(text.getLeftPadding());
731         int bottomPadding = twip(text.getBottomPadding());
732         int rightPadding = twip(text.getRightPadding());
733
734         Color JavaDoc bgcolor = text.getBackcolor();
735         
736         if (text.getMode() == JRElement.MODE_OPAQUE)
737         {
738             startGraphic("dprect", x, y, width, height);
739             finishGraphic(JRGraphicElement.PEN_NONE, text.getForecolor(), bgcolor, 1);
740         }
741         
742         int verticalAdjustment = topPadding;
743         switch (text.getVerticalAlignment())
744         {
745             case JRAlignment.VERTICAL_ALIGN_TOP:
746                 verticalAdjustment = 0;
747                 break;
748             case JRAlignment.VERTICAL_ALIGN_MIDDLE:
749                 verticalAdjustment = (height - topPadding - bottomPadding - twip(text.getTextHeight())) / 2;
750                 break;
751             case JRAlignment.VERTICAL_ALIGN_BOTTOM:
752                 verticalAdjustment = (height - topPadding - bottomPadding - twip(text.getTextHeight()));
753                 break;
754         }
755         
756         /*
757          rtf text box does not allow unicode characters
758          representation so if the report contains
759          unicode characters above 127 the text box
760          is replaced by paragraphs
761          */

762         if(isUnicode) {
763             writer.write("{\\pard\\absw");
764             writer.write(String.valueOf(width));
765             writer.write("\\absh");
766             writer.write(String.valueOf(textHeight));
767             writer.write("\\phpg\\posx");
768             writer.write(String.valueOf(x));
769             writer.write("\\pvpg\\posy");
770             writer.write(String.valueOf(y + verticalAdjustment + topPadding));
771         }
772         else {
773             writer.write("{\\*\\do\\dobxpage\\dobypage\\dodhgt");
774             writer.write(String.valueOf(zorder++));
775             writer.write("\\dptxbx\\dpx");
776             writer.write(String.valueOf(x + textBoxAdjustment));
777             writer.write("\\dpxsize");
778             writer.write(String.valueOf(width - textBoxAdjustment));
779             writer.write("\\dpy");
780             writer.write(String.valueOf(y + verticalAdjustment + topPadding + textBoxAdjustment));
781             writer.write("\\dpysize");
782             writer.write(String.valueOf(textHeight + bottomPadding - textBoxAdjustment));
783             writer.write("\\dpfillpat0\\dplinehollow{\\dptxbxtext {\\pard");
784         }
785         
786         JRFont font = text;
787
788         writer.write("\\f");
789         writer.write(String.valueOf(getFontIndex(font)));
790         writer.write("\\cf");
791         writer.write(String.valueOf(getColorIndex(text.getForecolor())));
792         writer.write("\\cb");
793         writer.write(String.valueOf(getColorIndex(bgcolor)));
794         writer.write(" ");
795
796         if (leftPadding > 0)
797         {
798             writer.write("\\li");
799             writer.write(String.valueOf(leftPadding));
800         }
801
802         if (rightPadding > 0)
803         {
804             writer.write("\\ri");
805             writer.write(String.valueOf(rightPadding));
806         }
807
808         if (font.isBold())
809             writer.write("\\b");
810         if (font.isItalic())
811             writer.write("\\i");
812         if (font.isStrikeThrough())
813             writer.write("\\strike");
814         if (font.isUnderline())
815             writer.write("\\ul");
816         writer.write("\\fs");
817         writer.write(String.valueOf(font.getFontSize() * 2));
818
819         switch (text.getHorizontalAlignment())
820         {
821             case JRAlignment.HORIZONTAL_ALIGN_LEFT:
822                 writer.write("\\ql");
823                 break;
824             case JRAlignment.HORIZONTAL_ALIGN_CENTER:
825                 writer.write("\\qc");
826                 break;
827             case JRAlignment.HORIZONTAL_ALIGN_RIGHT:
828                 writer.write("\\qr");
829                 break;
830             case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED:
831                 writer.write("\\qj");
832                 break;
833             default:
834                 writer.write("\\ql");
835                 break;
836         }
837
838         writer.write("\\sl");
839         writer.write(String.valueOf(twip(text.getLineSpacingFactor() * font.getFontSize())));
840         writer.write(" ");
841
842         // add parameters in case of styled text element
843
String JavaDoc plainText = styledText.getText();
844         int runLimit = 0;
845
846         AttributedCharacterIterator JavaDoc iterator = styledText.getAttributedString().getIterator();
847         while (
848             runLimit < styledText.length()
849             && (runLimit = iterator.getRunLimit()) <= styledText.length()
850             )
851         {
852
853             Map JavaDoc styledTextAttributes = iterator.getAttributes();
854             JRFont styleFont = new JRBaseFont(styledTextAttributes);
855             Color JavaDoc styleForeground = (Color JavaDoc) styledTextAttributes.get(TextAttribute.FOREGROUND);
856             Color JavaDoc styleBackground = (Color JavaDoc) styledTextAttributes.get(TextAttribute.BACKGROUND);
857             
858             writer.write("\\f");
859             writer.write(String.valueOf(getFontIndex(styleFont)));
860             writer.write("\\fs");
861             writer.write(String.valueOf(2 * styleFont.getFontSize()));
862
863             if (styleFont.isBold())
864             {
865                 writer.write("\\b");
866             }
867             if (styleFont.isItalic())
868             {
869                 writer.write("\\i");
870             }
871             if (styleFont.isUnderline())
872             {
873                 writer.write("\\ul");
874             }
875             if (styleFont.isStrikeThrough())
876             {
877                 writer.write("\\strike");
878             }
879
880             if (TextAttribute.SUPERSCRIPT_SUPER.equals(styledTextAttributes.get(TextAttribute.SUPERSCRIPT)))
881             {
882                 writer.write("\\super");
883             }
884             else if (TextAttribute.SUPERSCRIPT_SUB.equals(styledTextAttributes.get(TextAttribute.SUPERSCRIPT)))
885             {
886                 writer.write("\\sub");
887             }
888             
889             if(!(null == styleBackground || styleBackground.equals(bgcolor))){
890                 writer.write("\\highlight");
891                 writer.write(String.valueOf(getColorIndex(styleBackground)));
892             }
893             writer.write("\\cf");
894             writer.write(String.valueOf(getColorIndex(styleForeground)));
895             writer.write(" ");
896
897             int s = 0;
898             int e = 0;
899             String JavaDoc str = plainText.substring(iterator.getIndex(), runLimit);
900             
901             String JavaDoc pattern = "\n";
902             String JavaDoc replace = "\\line ";
903             StringBuffer JavaDoc result = new StringBuffer JavaDoc();
904
905             while ((e = str.indexOf(pattern, s)) >= 0)
906             {
907                 result.append(str.substring(s, e));
908                 result.append(replace);
909                 s = e + pattern.length();
910             }
911             result.append(str.substring(s));
912             
913             writer.write(handleUnicodeText(result, text.getRunDirection() == JRPrintText.RUN_DIRECTION_RTL));
914             
915             // reset all styles in the paragraph
916
writer.write("\\plain");
917
918             iterator.setIndex(runLimit);
919         }
920         
921         if(isUnicode) {
922             writer.write("\\par}\n");
923         }
924         else {
925             writer.write("\\par}}}\n");
926         }
927
928         exportBox(text, x, y, width, height, text.getForecolor(), bgcolor);
929     }
930     
931     
932     /**
933      * Replace Unicode characters with RTF Unicode control words
934      * @param source source text
935      * @return text with Unicode characters replaced
936      */

937     private String JavaDoc handleUnicodeText(StringBuffer JavaDoc source, boolean isRightToLeft)
938     {
939         StringBuffer JavaDoc resultBuffer = new StringBuffer JavaDoc();
940         StringBuffer JavaDoc leftToRightBuffer = new StringBuffer JavaDoc();
941         
942         for(int i = 0; i < source.length(); i++ )
943         {
944             long ch = source.charAt(i);
945             if(ch > 127)
946             {
947                 if(isRightToLeft)
948                 {
949                     resultBuffer.insert(0, leftToRightBuffer.toString());
950                     leftToRightBuffer = new StringBuffer JavaDoc();
951                     
952                     resultBuffer.insert(0, "\\u" + ch + '?');
953                 }
954                 else
955                 {
956                     leftToRightBuffer.append("\\u" + ch + '?');
957                 }
958             }
959             else
960             {
961                 leftToRightBuffer.append((char)ch);
962             }
963         }
964         
965         if(leftToRightBuffer != null && leftToRightBuffer.length() > 0)
966         {
967             if(isRightToLeft)
968             {
969                 resultBuffer.insert(0, leftToRightBuffer.toString());
970             }
971             else
972             {
973                 resultBuffer.append(leftToRightBuffer.toString());
974             }
975         }
976         
977         return resultBuffer.toString();
978     }
979     
980     
981     /**
982      * Export a image object
983      * @param printImage JasperReports image object (JRPrintImage)
984      * @throws JRException
985      * @throws IOException
986      */

987     protected void exportImage(JRPrintImage printImage) throws JRException, IOException JavaDoc
988     {
989         int x = twip(printImage.getX() + globalOffsetX);
990         int y = twip(printImage.getY() + globalOffsetY);
991         int width = twip(printImage.getWidth());
992         int height = twip(printImage.getHeight());
993
994         if (printImage.getMode() == JRElement.MODE_OPAQUE)
995         {
996             startGraphic("dprect", x, y, width, height);
997             finishGraphic(JRGraphicElement.PEN_NONE, printImage.getForecolor(),
998                     printImage.getBackcolor(), 1);
999         }
1000
1001        int leftPadding = printImage.getLeftPadding();
1002        int topPadding = printImage.getTopPadding();
1003        int rightPadding = printImage.getRightPadding();
1004        int bottomPadding = printImage.getBottomPadding();
1005
1006        int availableImageWidth = printImage.getWidth() - leftPadding - rightPadding;
1007        availableImageWidth = availableImageWidth < 0 ? 0 : availableImageWidth;
1008
1009        int availableImageHeight = printImage.getHeight() - topPadding - bottomPadding;
1010        availableImageHeight = availableImageHeight < 0 ? 0 : availableImageHeight;
1011
1012        JRRenderable renderer = printImage.getRenderer();
1013
1014        if (availableImageWidth > 0 && availableImageHeight > 0 && renderer != null)
1015        {
1016            int normalWidth = availableImageWidth;
1017            int normalHeight = availableImageHeight;
1018
1019            Dimension2D JavaDoc dimension = renderer.getDimension();
1020            if (dimension != null)
1021            {
1022                normalWidth = (int) dimension.getWidth();
1023                normalHeight = (int) dimension.getHeight();
1024            }
1025
1026            float xalignFactor = 0f;
1027            switch (printImage.getHorizontalAlignment())
1028            {
1029                case JRAlignment.HORIZONTAL_ALIGN_RIGHT:
1030                {
1031                    xalignFactor = 1f;
1032                    break;
1033                }
1034                case JRAlignment.HORIZONTAL_ALIGN_CENTER:
1035                {
1036                    xalignFactor = 0.5f;
1037                    break;
1038                }
1039                case JRAlignment.HORIZONTAL_ALIGN_LEFT:
1040                default:
1041                {
1042                    xalignFactor = 0f;
1043                    break;
1044                }
1045            }
1046
1047            float yalignFactor = 0f;
1048            switch (printImage.getVerticalAlignment())
1049            {
1050                case JRAlignment.VERTICAL_ALIGN_BOTTOM:
1051                {
1052                    yalignFactor = 1f;
1053                    break;
1054                }
1055                case JRAlignment.VERTICAL_ALIGN_MIDDLE:
1056                {
1057                    yalignFactor = 0.5f;
1058                    break;
1059                }
1060                case JRAlignment.VERTICAL_ALIGN_TOP:
1061                default:
1062                {
1063                    yalignFactor = 0f;
1064                    break;
1065                }
1066            }
1067
1068            BufferedImage JavaDoc bi = new BufferedImage JavaDoc(availableImageWidth, availableImageHeight, BufferedImage.TYPE_INT_RGB);
1069            Graphics2D JavaDoc grx = bi.createGraphics();
1070            grx.setColor(printImage.getBackcolor());//FIXMEIMAGE ignore mode? what about alpha channel above?
1071
grx.fillRect(0, 0, availableImageWidth, availableImageHeight);
1072
1073            switch (printImage.getScaleImage())
1074            {
1075                case JRImage.SCALE_IMAGE_CLIP:
1076                {
1077                    int xoffset = (int) (xalignFactor * (availableImageWidth - normalWidth));
1078                    int yoffset = (int) (yalignFactor * (availableImageHeight - normalHeight));
1079
1080                    renderer.render(grx, new Rectangle JavaDoc(xoffset, yoffset,
1081                            normalWidth, normalHeight));
1082
1083                    break;
1084                }
1085                case JRImage.SCALE_IMAGE_FILL_FRAME:
1086                {
1087                    renderer.render(grx, new Rectangle JavaDoc(0, 0,
1088                            availableImageWidth, availableImageHeight));
1089
1090                    break;
1091                }
1092                case JRImage.SCALE_IMAGE_RETAIN_SHAPE:
1093                default:
1094                {
1095                    if (printImage.getHeight() > 0)
1096                    {
1097                        double ratio = (double) normalWidth / (double) normalHeight;
1098
1099                        if (ratio > (double) availableImageWidth / (double) availableImageHeight)
1100                        {
1101                            normalWidth = availableImageWidth;
1102                            normalHeight = (int) (availableImageWidth / ratio);
1103                        }
1104                        else
1105                        {
1106                            normalWidth = (int) (availableImageHeight * ratio);
1107                            normalHeight = availableImageHeight;
1108                        }
1109
1110                        int xoffset = (int) (xalignFactor * (availableImageWidth - normalWidth));
1111                        int yoffset = (int) (yalignFactor * (availableImageHeight - normalHeight));
1112
1113                        renderer.render(grx, new Rectangle JavaDoc(xoffset, yoffset,
1114                                normalWidth, normalHeight));
1115                    }
1116
1117                    break;
1118                }
1119            }
1120            
1121            writer.write("{\\*\\do\\dobxpage\\dobypage\\dodhgt");
1122            writer.write(String.valueOf(zorder++));
1123            writer.write("\\dptxbx\\dpx");
1124            writer.write(String.valueOf(twip(printImage.getX() + leftPadding + globalOffsetX + getOffsetX())));
1125            writer.write("\\dpxsize");
1126            writer.write(String.valueOf(twip(availableImageWidth)));
1127            writer.write("\\dpy");
1128            writer.write(String.valueOf(twip(printImage.getY() + topPadding + globalOffsetY + getOffsetY())));
1129            writer.write("\\dpysize");
1130            writer.write(String.valueOf(twip(availableImageHeight)));
1131            writer.write("\\dpfillpat0\\dplinehollow{\\dptxbxtext {\\pict\\jpegblip\\picwgoal");
1132            writer.write(String.valueOf(twip(availableImageWidth)));
1133            writer.write("\\pichgoal");
1134            writer.write(String.valueOf(twip(availableImageHeight)));
1135            writer.write("\n");
1136            
1137            ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(JRImageLoader.loadImageDataFromAWTImage(bi, JRRenderable.IMAGE_TYPE_JPEG));
1138
1139            int count = 0;
1140            int current = 0;
1141            while ((current = bais.read()) != -1)
1142            {
1143                String JavaDoc helperStr = Integer.toHexString(current);
1144                if (helperStr.length() < 2)
1145                {
1146                    helperStr = "0" + helperStr;
1147                }
1148                writer.write(helperStr);
1149                count++;
1150                if (count == 64)
1151                {
1152                    writer.write("\n");
1153                    count = 0;
1154                }
1155            }
1156
1157            writer.write("\n}}}\n");
1158        }
1159
1160        if (
1161            printImage.getTopBorder() == JRGraphicElement.PEN_NONE &&
1162            printImage.getLeftBorder() == JRGraphicElement.PEN_NONE &&
1163            printImage.getBottomBorder() == JRGraphicElement.PEN_NONE &&
1164            printImage.getRightBorder() == JRGraphicElement.PEN_NONE
1165            )
1166        {
1167            if (printImage.getPen() != JRGraphicElement.PEN_NONE)
1168            {
1169                startGraphic("dprect", x, y, width, height);
1170                finishGraphic(printImage);
1171            }
1172        }
1173        else
1174        {
1175            exportBox(printImage, x, y, width, height, printImage.getForecolor(), printImage.getBackcolor());
1176        }
1177    }
1178    
1179    /**
1180     *
1181     * @param frame
1182     * @throws JRException
1183     */

1184    protected void exportFrame(JRPrintFrame frame) throws JRException, IOException JavaDoc {
1185        int x = twip(frame.getX() + getOffsetX());
1186        int y = twip(frame.getY() + getOffsetY());
1187        int width = twip(frame.getWidth());
1188        int height = twip(frame.getHeight());
1189        
1190        if (frame.getMode() == JRElement.MODE_OPAQUE)
1191        {
1192            startGraphic("dprect", x, y, width, height);
1193            finishGraphic(JRGraphicElement.PEN_NONE, frame.getForecolor(),
1194                    frame.getBackcolor(), 1);
1195        }
1196        
1197        setFrameElementsOffset(frame, false);
1198        exportElements(frame.getElements());
1199        restoreElementOffsets();
1200        
1201        exportBox(frame, x, y, width, height, frame.getForecolor(), frame.getBackcolor());
1202    }
1203    
1204    
1205    protected void exportElements(Collection JavaDoc elements) throws JRException, IOException JavaDoc {
1206        if (elements != null && elements.size() > 0) {
1207            for (Iterator JavaDoc it = elements.iterator(); it.hasNext();) {
1208                JRPrintElement element = (JRPrintElement)it.next();
1209                if (element instanceof JRPrintLine) {
1210                    exportLine((JRPrintLine)element);
1211                }
1212                else if (element instanceof JRPrintRectangle) {
1213                    exportRectangle((JRPrintRectangle)element);
1214                }
1215                else if (element instanceof JRPrintEllipse) {
1216                    exportEllipse((JRPrintEllipse)element);
1217                }
1218                else if (element instanceof JRPrintImage) {
1219                    exportImage((JRPrintImage)element);
1220                }
1221                else if (element instanceof JRPrintText) {
1222                    exportText((JRPrintText)element);
1223                }
1224                else if (element instanceof JRPrintFrame) {
1225                    exportFrame((JRPrintFrame)element);
1226                }
1227            }
1228        }
1229    }
1230    
1231    /**
1232     * Exports a JRBox that represents the border of a JasperReports object
1233     * @param box
1234     * @param x
1235     * @param y
1236     * @param width
1237     * @param height
1238     * @param fg
1239     * @param bg
1240     * @throws IOException
1241     */

1242    private void exportBox(JRBox box, int x, int y, int width, int height, Color JavaDoc fg, Color JavaDoc bg) throws IOException JavaDoc{
1243        
1244        if (box.getTopBorder() != JRGraphicElement.PEN_NONE) {
1245            Color JavaDoc bc = box.getTopBorderColor();
1246            byte pen = box.getTopBorder();
1247            
1248            int a = getAdjustment(box.getTopBorder());
1249            if (bc == null) {
1250                bc = fg;
1251            }
1252            startGraphic("dpline", x, y + a, width, 0);
1253            finishGraphic(pen, bc, bg, 1);
1254            
1255        }
1256        if (box.getLeftBorder() != JRGraphicElement.PEN_NONE)
1257        {
1258            Color JavaDoc bc = box.getLeftBorderColor();
1259            byte pen = box.getLeftBorder();
1260            int a = getAdjustment(pen);
1261            if (bc == null)
1262                bc = fg;
1263            startGraphic("dpline", x + a, y, 0, height);
1264            finishGraphic(pen, bc, bg, 1);
1265
1266        }
1267
1268        if (box.getBottomBorder() != JRGraphicElement.PEN_NONE)
1269        {
1270            Color JavaDoc bc = box.getBottomBorderColor();
1271            byte pen = box.getBottomBorder();
1272            int a = getAdjustment(pen);
1273            if (bc == null)
1274                bc = fg;
1275            startGraphic("dpline", x, y + height - a, width, 0);
1276            finishGraphic(pen, bc, bg, 1);
1277        }
1278
1279        if (box.getRightBorder() != JRGraphicElement.PEN_NONE)
1280        {
1281            Color JavaDoc bc = box.getRightBorderColor();
1282            byte pen = box.getRightBorder();
1283            int a = getAdjustment(pen);
1284            if (bc == null)
1285                bc = fg;
1286            startGraphic("dpline", x + width - a, y, 0, height);
1287            finishGraphic(pen, bc, bg, 1);
1288        }
1289    }
1290}
1291
Popular Tags