2176f340b68d31eb5d03fad1de977431f171d7fb
[mir.git] / source / mircoders / pdf / PDFGenerator.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License, 
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
23  * (or with modified versions of the above that use the same license as the above), 
24  * and distribute linked combinations including the two.  You must obey the 
25  * GNU General Public License in all respects for all of the code used other than 
26  * the above mentioned libraries.  If you modify this file, you may extend this 
27  * exception to your version of the file, but you are not obligated to do so.  
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mircoders.pdf;
31
32 import gnu.regexp.RE;
33 import gnu.regexp.REException;
34
35 import java.io.ByteArrayOutputStream;
36 import java.io.IOException;
37 import java.net.MalformedURLException;
38
39 import mir.config.MirPropertiesConfiguration;
40 import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
41 import mir.entity.EntityList;
42 import mir.log.LoggerWrapper;
43 import mircoders.entity.EntityContent;
44 import mircoders.entity.EntityImages;
45 import mircoders.storage.DatabaseContentToMedia;
46
47 import com.lowagie.text.BadElementException;
48 import com.lowagie.text.Document;
49 import com.lowagie.text.DocumentException;
50 import com.lowagie.text.Element;
51 import com.lowagie.text.Font;
52 import com.lowagie.text.Image;
53 import com.lowagie.text.PageSize;
54 import com.lowagie.text.Paragraph;
55 import com.lowagie.text.Phrase;
56 import com.lowagie.text.pdf.BaseFont;
57 import com.lowagie.text.pdf.ColumnText;
58 import com.lowagie.text.pdf.PdfContentByte;
59 import com.lowagie.text.pdf.PdfTemplate;
60 import com.lowagie.text.pdf.PdfWriter;
61
62
63
64 public class PDFGenerator{
65
66   public Document document;
67   public PdfWriter writer;
68   public PdfContentByte cb;
69   public String localImageDir;
70   public float currentYPosition;
71   public int currentPage;
72   public float pageWidth;
73   public float pageHeight;
74   public float verticalMargin;
75   public float horizontalMargin;
76   public float topEdge;
77   public float bottomEdge;
78   public float rightEdge;
79   public float leftEdge;
80
81   public int    maxImageHeight;   
82   public int    maxImageWidth;    
83   protected LoggerWrapper logger;
84
85   public int indexFontSize; 
86   public int indexLineHeight; 
87   public int indexFontFamily; 
88
89   public float footerHeight;
90   public String footerText;
91   public int footerFontSize; 
92   public int footerFontFamily; 
93
94   public int metaHeight;
95   public int metaFontSize;
96   public int metaFontFamily;
97
98   public int descriptionLineHeight;
99   public int descriptionFontSize;
100   public int descriptionFontFamily;
101
102   public int contentLineHeight;
103   public int contentFontSize;
104   public int contentFontFamily;
105
106   public int sourceLineHeight;
107   public int sourceFontSize;
108   public int sourceFontFamily;
109
110   public int bigImageCaptionFontSize;
111   public int bigImageCaptionFontFamily;
112
113   protected MirPropertiesConfiguration configuration;
114
115
116   public PDFGenerator(ByteArrayOutputStream out){
117     logger = new LoggerWrapper("PDFGenerator");
118     try {
119       configuration = MirPropertiesConfiguration.instance();
120     }
121     catch (PropertiesConfigExc e) {
122       throw new RuntimeException("Can't get configuration: " + e.getMessage());
123     }
124     localImageDir=configuration.getString("Producer.Image.Path");
125
126     try {
127       indexFontSize   = Integer.parseInt(configuration.getString("PDF.Index.FontSize"));
128       indexLineHeight = Integer.parseInt(configuration.getString("PDF.Index.LineHeight"));
129       indexFontFamily = getFontByName(configuration.getString("PDF.Index.FontFamily"));
130       
131       footerText = configuration.getString("PDF.Footer.String");
132       footerFontSize   = Integer.parseInt(configuration.getString("PDF.Footer.FontSize"));
133       footerFontFamily = getFontByName(configuration.getString("PDF.Footer.FontFamily"));
134       footerHeight = Integer.parseInt(configuration.getString("PDF.Footer.Height"));;
135       
136       metaFontSize   = Integer.parseInt(configuration.getString("PDF.Meta.FontSize"));
137       metaFontFamily = getFontByName(configuration.getString("PDF.Meta.FontFamily"));
138       metaHeight = Integer.parseInt(configuration.getString("PDF.Meta.Height"));;
139       
140       descriptionFontSize   = Integer.parseInt(configuration.getString("PDF.Description.FontSize"));
141       descriptionLineHeight = Integer.parseInt(configuration.getString("PDF.Description.LineHeight"));
142       descriptionFontFamily = getFontByName(configuration.getString("PDF.Description.FontFamily"));
143       
144       contentFontSize   = Integer.parseInt(configuration.getString("PDF.Content.FontSize"));
145       contentLineHeight = Integer.parseInt(configuration.getString("PDF.Content.LineHeight"));
146       contentFontFamily = getFontByName(configuration.getString("PDF.Content.FontFamily"));
147       
148       sourceFontSize   = Integer.parseInt(configuration.getString("PDF.Source.FontSize"));
149       sourceLineHeight = Integer.parseInt(configuration.getString("PDF.Source.LineHeight"));
150       sourceFontFamily = getFontByName(configuration.getString("PDF.Source.FontFamily"));
151       
152       bigImageCaptionFontSize   = Integer.parseInt(configuration.getString("PDF.BigImageCaption.FontSize"));
153       bigImageCaptionFontFamily = getFontByName(configuration.getString("PDF.BigImageCaption.FontFamily"));
154     
155     }
156     catch (NumberFormatException e){
157       e.printStackTrace();
158     }
159
160     // step 1: make a document
161     
162     String pageSize = configuration.getString("PDF.Pagesize");
163     
164     if (pageSize.equals("LETTER")){
165       document = new Document(PageSize.LETTER);
166       pageWidth = 612;
167       pageHeight = 792;
168     }
169     else {
170        document = new Document(PageSize.A4);
171        pageWidth=595;
172        pageHeight=842;
173     }
174
175     maxImageHeight    = 250;
176     maxImageWidth     = 250;
177         
178    
179     verticalMargin = 20;
180     horizontalMargin = 20;
181     
182
183     
184     topEdge=pageHeight-verticalMargin;
185     bottomEdge=verticalMargin;
186     rightEdge=pageWidth-horizontalMargin;
187     leftEdge=horizontalMargin;
188     
189     currentYPosition=topEdge;
190     currentPage = 1;
191     
192     String headerText = configuration.getString("PDF.Title.String");
193     
194     try{
195       writer = PdfWriter.getInstance(document, out);
196       cb = writer.getDirectContent();
197       
198       document.open();      
199       addHeader(headerText);
200     }
201     catch(DocumentException de) {
202       logger.error(de.getMessage());
203     }
204   }
205   
206   public void stop(){
207     addFooter();
208     document.close();
209   }
210
211   public void addHeader(String headerText){
212     int titleFontSize=Integer.parseInt(configuration.getString("PDF.Title.FontSize"));
213     int titleLineHeight=Integer.parseInt(configuration.getString("PDF.Title.LineHeight"));
214     String titleFontFamily=configuration.getString("PDF.Title.FontFamily");
215     
216     try {
217            
218       ColumnText ct = new ColumnText(cb);   
219       //add a basic header
220       ct.addText(new Phrase(headerText, new Font(getFontByName(titleFontFamily), titleFontSize,Font.BOLD)));
221       float[] rightCol = {rightEdge,topEdge,rightEdge,topEdge-titleLineHeight};
222       float[] leftCol = {leftEdge,topEdge,leftEdge,topEdge-titleLineHeight};
223       ct.setColumns(leftCol,rightCol);
224       ct.setYLine(topEdge);
225       ct.setAlignment(Element.ALIGN_CENTER);
226       ct.go();
227       
228       currentYPosition = currentYPosition - titleLineHeight;
229       
230     }
231     catch(DocumentException de) {
232       logger.error(de.getMessage());
233     }
234   }
235
236   public void addIndexItem(EntityContent entityContent){
237     try {
238
239       ColumnText ict = new ColumnText(cb);
240       String theTitle = entityContent.getValue("title");
241       String theCreator = entityContent.getValue("creator");
242       Phrase titleP=new Phrase(" - " +  theTitle,new Font(indexFontFamily,indexFontSize,Font.BOLD));
243       Phrase creatorP=new Phrase( " :: " + theCreator,new Font(indexFontFamily,indexFontSize));
244       float toYPosition = currentYPosition - indexLineHeight;
245       float[] leftIndexCols = {leftEdge,currentYPosition,leftEdge,toYPosition};
246       float[] rightIndexCols = {rightEdge,currentYPosition,rightEdge,toYPosition};
247       ict.addText(titleP);
248       ict.addText(creatorP);
249       ict.setColumns(leftIndexCols,rightIndexCols);
250       ict.setYLine(currentYPosition);
251       ict.setAlignment(Element.ALIGN_LEFT);
252       int status=ict.go();
253       currentYPosition = toYPosition;
254     }
255     catch(DocumentException de) {
256       logger.error(de.getMessage());
257     }
258     
259
260
261   }
262
263   private int addTextLine(ColumnText ct,int lineHeight,int alignment,float left, float right){
264     logger.debug("adding a line of text");
265     if (! enoughY(lineHeight)){
266       newPage();
267     }
268     float toYPosition = currentYPosition - lineHeight;
269     float[] leftContentCols = {left,currentYPosition,left,toYPosition};
270     float[] rightContentCols = {right,currentYPosition,right,toYPosition};
271     ct.setColumns(leftContentCols,rightContentCols);
272     ct.setYLine(currentYPosition);
273     ct.setAlignment(alignment);
274     try{
275       int status=ct.go();
276       currentYPosition = toYPosition;
277       return status;
278     }
279     catch(DocumentException de) {
280       logger.error(de.getMessage());
281     }
282     return 0;
283   }
284
285   public void addLine(){
286     cb.setLineWidth(1f);
287     cb.moveTo(rightEdge, currentYPosition-5);
288     cb.lineTo(leftEdge, currentYPosition-5);
289     cb.stroke();
290     currentYPosition = currentYPosition - 10;
291     
292   }
293   
294   public void addFooter(){
295     try{
296     ColumnText fct = new ColumnText(cb);
297     cb.setLineWidth(1f);
298     cb.moveTo(rightEdge, bottomEdge+footerHeight-5);
299     cb.lineTo(leftEdge, bottomEdge+footerHeight-5);
300     cb.stroke();
301     float[] leftFooterCols = {leftEdge,bottomEdge+footerHeight-1,leftEdge,bottomEdge};
302     float[] rightFooterCols = {rightEdge,bottomEdge+footerHeight-1,rightEdge,bottomEdge};
303     
304     Paragraph footerP=new Paragraph(footerText,new Font(footerFontFamily,footerFontSize));
305     fct.addText(footerP);
306     
307     fct.setColumns(leftFooterCols,rightFooterCols);
308     fct.setYLine(bottomEdge+footerHeight-1);
309     fct.setAlignment(Element.ALIGN_JUSTIFIED);
310     int status=fct.go();
311
312     Paragraph numberP=new Paragraph((new Integer(currentPage)).toString(),new Font(footerFontFamily,footerFontSize,Font.BOLD));
313     fct.addText(numberP);
314     fct.setAlignment(Element.ALIGN_RIGHT);
315     status=fct.go();
316
317     }
318     catch (DocumentException de){
319       logger.error(de.getMessage());
320     }
321
322
323   }
324
325   public void newPage(){
326     try{
327       //add a footer
328       addFooter();
329       document.newPage();   
330       currentPage++;
331       currentYPosition=topEdge;
332     }
333     catch(DocumentException de) {
334       logger.error(de.getMessage());
335     }
336   }
337   
338   public void addArticleSeparator(){
339     // make a line 
340     if (! enoughY(10)){
341       newPage();
342     }
343     cb.setLineWidth(1f);
344     cb.moveTo(rightEdge, currentYPosition-5);
345     cb.lineTo(leftEdge, currentYPosition-5);
346     cb.stroke();
347     currentYPosition = currentYPosition - 10;
348   }
349
350   public void addArticleMetaInfo(ColumnText ct,String theTitle,String theCreator,String theDate){
351       //see if we have room for the author and title
352     
353     if (! enoughY(metaHeight)){
354         newPage();
355       }
356     
357     Paragraph titleP=new Paragraph(theTitle+"\n",new Font(metaFontFamily,metaFontSize,Font.BOLD));
358     Paragraph whowhenP=new Paragraph(theCreator + "  " + theDate ,new Font(metaFontFamily,metaFontSize));
359     ct.addText(titleP);
360     ct.addText(whowhenP);
361     
362     ct.setYLine(currentYPosition);
363     ct.setAlignment(Element.ALIGN_LEFT);
364     
365     float toYPosition = currentYPosition - metaHeight;
366     float[] leftHeadCols = {leftEdge,currentYPosition,leftEdge,toYPosition};
367     float[] rightHeadCols = {rightEdge,currentYPosition,rightEdge,toYPosition};
368     
369     ct.setColumns(leftHeadCols,rightHeadCols);
370     try { 
371       ct.go();
372       currentYPosition = toYPosition;
373     }
374     catch(DocumentException de) {
375       logger.error(de.getMessage());
376     }
377     
378   }
379
380   public void addArticleDescription(ColumnText ct,String theDescription){
381     // Now we add the description, one line at a time, the ct should be empty at this point
382     
383     
384     Paragraph descP=new Paragraph(theDescription,new Font(descriptionFontFamily,descriptionFontSize,Font.BOLD));
385     ct.addText(descP);
386     
387     // every article has a description, so we can assume that:
388     int status = ColumnText.NO_MORE_COLUMN;
389     
390     int brake=1000; 
391     while ((status & ColumnText.NO_MORE_TEXT) == 0 && brake >0){
392       //there is still text left in the description.
393       status = addTextLine(ct,descriptionLineHeight,Element.ALIGN_JUSTIFIED,leftEdge,rightEdge);
394       brake--;
395     }
396     if (brake == 0)
397       logger.error("runaway description...try increasing the line height or decreasing the font size");
398   }
399  
400   public void addArticleContent(ColumnText ct,String theContent,EntityList images){
401     //let's go ahead and add in all the body text
402     Paragraph contentP=new Paragraph(theContent,new Font(contentFontFamily,contentFontSize));
403     ct.addText(contentP);
404     
405     int contentLinesBeforeImages=3;
406     //and assume we have at least one line of text in the content
407     int status = ColumnText.NO_MORE_COLUMN;
408     
409     // let's add a little bit of text, like a couple of lines
410     int x = 0;
411     while (((status & ColumnText.NO_MORE_TEXT) == 0) && x<contentLinesBeforeImages){
412       status=addTextLine(ct,contentLineHeight,Element.ALIGN_JUSTIFIED,leftEdge,rightEdge);
413       x++;
414     }
415
416     boolean addImageOnLeft = true; //we will alternate within articles
417     while (images.hasNext()){
418       
419       EntityImages currentImage=(EntityImages) images.next();
420       float img_width=(new Float(currentImage.getValue("img_width"))).floatValue();
421       float img_height=(new Float(currentImage.getValue("img_height"))).floatValue();
422       if (img_height>maxImageHeight){
423         img_width=(new Float((new Float(img_width*(maxImageHeight/img_height))).intValue())).floatValue();
424         img_height=maxImageHeight;
425       }
426       if (img_width>maxImageWidth){
427         img_height=(new Float((new Float(img_height*(maxImageWidth/img_width))).intValue())).floatValue();
428         img_width=maxImageWidth;
429       }
430
431       String img_title=currentImage.getValue("title");
432       String img_path=currentImage.getValue("publish_path");
433       
434       if ((status & ColumnText.NO_MORE_TEXT) == 0){ 
435         // there is still text, so add an image which will have text wrapped around it, then add the text which 
436         // will be on the left or the right of the image
437         
438         float templateMinimumHeight = img_height+20;
439         float templateWidth = img_width+10;
440         float templateHeight = templateMinimumHeight+contentLineHeight-(templateMinimumHeight % contentLineHeight);
441         
442         PdfTemplate template = cb.createTemplate(templateWidth,templateHeight); 
443         
444         
445         //here we need a page check
446         if (! enoughY((new Float(templateHeight)).intValue())){
447           //ok, well just fill text to the bottom then
448           float toYPosition = bottomEdge+footerHeight;
449           float[] leftBottomCols = {leftEdge,currentYPosition,leftEdge,toYPosition};
450           float[] rightBottomCols = {rightEdge,currentYPosition,rightEdge,toYPosition};
451           ct.setColumns(leftBottomCols,rightBottomCols);
452           ct.setYLine(currentYPosition);
453           ct.setAlignment(Element.ALIGN_JUSTIFIED);
454           try{ 
455             status=ct.go();
456           }
457           catch(DocumentException de) {
458             logger.error(de.getMessage());
459           }
460           newPage();
461         }
462         
463         float toYPosition=currentYPosition - templateHeight;
464
465         try {
466           Image theImage = Image.getInstance(localImageDir+img_path);
467           theImage.scaleAbsolute(img_width,img_height);
468           theImage.setAbsolutePosition(5,13); 
469           
470           template.addImage(theImage);
471           template.beginText();
472           BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
473           template.setFontAndSize(bf, 8);
474           template.setTextMatrix(5, 3);
475           template.showText(img_title);
476           template.endText();
477         }
478         catch(BadElementException de) {
479           logger.error(de.getMessage());
480         }
481         catch(DocumentException de) {
482           logger.error(de.getMessage());
483         }
484         catch (MalformedURLException de){
485          logger.error(de.getMessage());
486         }
487         catch (IOException de){
488           logger.error(de.getMessage());
489         }
490
491         
492         float leftImageTextEdge=leftEdge;
493         float rightImageTextEdge=rightEdge;
494         
495         
496         if (addImageOnLeft){
497           cb.addTemplate(template,leftEdge,toYPosition);
498           leftImageTextEdge=leftEdge+templateWidth+5;
499           addImageOnLeft = false;
500         }           
501         else {
502           cb.addTemplate(template,rightEdge-templateWidth,toYPosition);
503           rightImageTextEdge = rightEdge-templateWidth-5;
504           addImageOnLeft = true;
505         }
506
507         logger.debug("adding template at " + leftEdge + "," + toYPosition);
508         
509         //and fill some text while we are at it
510         
511         float[] leftBottomCols = {leftImageTextEdge,currentYPosition,leftImageTextEdge,toYPosition};
512         float[] rightBottomCols = {rightImageTextEdge,currentYPosition,rightImageTextEdge,toYPosition};
513         ct.setColumns(leftBottomCols,rightBottomCols);
514         ct.setYLine(currentYPosition);
515         ct.setAlignment(Element.ALIGN_JUSTIFIED);
516         try{ 
517         status=ct.go();
518         currentYPosition=toYPosition;
519         }
520         catch(DocumentException de) {
521           logger.error(de.getMessage());
522         }
523         
524         
525       }
526       else { 
527         //add an image on the left with a big caption to the right
528         currentYPosition = currentYPosition - 10;
529         float templateMinimumHeight = img_height;
530         float templateWidth = img_width;
531         float templateHeight = templateMinimumHeight+contentLineHeight-(templateMinimumHeight % contentLineHeight);
532         PdfTemplate template = cb.createTemplate(templateWidth,templateHeight); 
533         if (! enoughY((new Float(templateHeight)).intValue())){
534           newPage();
535         }
536         float toYPosition=currentYPosition - templateHeight;
537         try{ 
538           Image theImage = Image.getInstance(localImageDir+img_path);
539           theImage.setAbsolutePosition(0,13); 
540           theImage.scaleAbsolute(img_width,img_height);
541           template.addImage(theImage);
542         }
543         catch(BadElementException de) {
544           logger.error(de.getMessage());
545         }
546         catch(DocumentException de) {
547           logger.error(de.getMessage());
548         }
549         catch(MalformedURLException de) {
550           logger.error(de.getMessage());
551         }
552         catch(IOException de) {
553           logger.error(de.getMessage());
554         }
555
556         cb.addTemplate(template,leftEdge,toYPosition);
557           
558         // add a big caption
559         ColumnText cct = new ColumnText(cb);   
560         float[] leftCaptionCols = {leftEdge+templateWidth+5,currentYPosition-5,leftEdge+templateWidth+5,toYPosition};
561         float[] rightCaptionCols = {rightEdge,currentYPosition-5,rightEdge,toYPosition};
562         
563         Paragraph captionP=new Paragraph(img_title,new Font(bigImageCaptionFontFamily,bigImageCaptionFontSize,Font.BOLD));
564         cct.addText(captionP);
565         cct.setColumns(leftCaptionCols,rightCaptionCols);
566         cct.setYLine(currentYPosition-5);
567         cct.setAlignment(Element.ALIGN_LEFT);
568         try{
569           cct.go();
570           currentYPosition=toYPosition;
571         }
572         catch(DocumentException de) {
573           logger.error(de.getMessage());
574         }
575       }
576     }
577     
578     //add the rest of the text which might be left
579     int brake = 10000;
580     while ((status & ColumnText.NO_MORE_TEXT) == 0  && brake > 0){
581       status=addTextLine(ct,contentLineHeight,Element.ALIGN_JUSTIFIED,leftEdge,rightEdge);
582       brake --;
583     }
584     if (brake == 0)
585       logger.error("runaway content....try decreasing font size or increasing line height");
586   }
587
588   private void addArticleSource(ColumnText ct,String theSource){
589     Paragraph sourceP = new Paragraph(theSource,new Font(sourceFontFamily,sourceFontSize,Font.BOLD));
590     ct.addText(sourceP);
591     addTextLine(ct,sourceLineHeight,Element.ALIGN_RIGHT,leftEdge,rightEdge);
592   }
593
594
595   private boolean enoughY(int heightOfBlockToAdd){
596     if ((currentYPosition - heightOfBlockToAdd - footerHeight) < bottomEdge )
597       return false;
598     else 
599       return true;
600   }
601   
602   
603   public void add(EntityContent entityContent){
604     logger.error("adding a content Entity");
605     
606     /*
607      * initialize
608      * separate
609      * meta info
610      * description
611      * content  
612      * --image with text
613      * --normal text
614      * --image without text
615      * source
616     */
617     
618     EntityList images=DatabaseContentToMedia.getInstance().getImages(entityContent);
619     String theTitle = entityContent.getValue("title");
620     String theCreator = entityContent.getValue("creator");
621     String theDate = entityContent.getValue("webdb_create_formatted");
622     String theDescriptionRaw = entityContent.getValue("description");
623     String theContentRaw = entityContent.getValue("content_data");
624     String theSource =  configuration.getString("Producer.ProductionHost") + "/" + configuration.getString("StandardLanguage") + entityContent.getValue("publish_path") + entityContent.getValue("id") + ".shtml";
625
626
627     
628     String theContent = "";
629     String theDescription = "";
630     
631     try { 
632       RE re1 = new RE("\r?\n\r?\n");
633       String theContent1 = re1.substituteAll(theContentRaw,"BREAKHERE");
634       String theDescription1 = re1.substituteAll(theDescriptionRaw,"BREAKHERE");
635       
636       RE re2 = new RE("\r?\n");
637       String theContent2 = re2.substituteAll(theContent1," ");
638       String theDescription2 = re2.substituteAll(theDescription1," ");
639       
640       RE re3 = new RE("BREAKHERE");
641       theContent = "    " + re3.substituteAll(theContent2,"\n    ");
642       theDescription = re3.substituteAll(theDescription2,"\n    ");
643
644     }
645     catch(REException ree){
646       logger.error(ree.getMessage());
647     }
648
649
650     addArticleSeparator();
651     
652     ColumnText ct = new ColumnText(cb);
653     
654     addArticleMetaInfo(ct,theTitle,theCreator,theDate);
655     addArticleDescription(ct,theDescription);
656     addArticleContent(ct,theContent,images);
657     addArticleSource(ct,theSource);
658       
659   }
660
661   public int getFontByName(String fontName) {
662     int theFont = 0;
663     if (fontName.equalsIgnoreCase("helvetica")){
664       theFont = Font.HELVETICA;
665     }
666     else {
667       if (fontName.equalsIgnoreCase("courier")) { 
668         theFont = Font.COURIER;
669       }
670       else {
671         if (fontName.equalsIgnoreCase("times")) { 
672           theFont = Font.TIMES_ROMAN;
673         }
674         else {
675           logger.error("using helvetica because I can't get font for name: "+fontName);
676           theFont = Font.HELVETICA;
677         }
678       }
679     }
680     
681     return theFont;
682
683   }
684 }
685
686