From d9dc67a1f7a8bf8a024bbe4551e88d5ff444c756 Mon Sep 17 00:00:00 2001 From: john Date: Mon, 14 Apr 2003 19:18:06 +0000 Subject: [PATCH] the class that generates PDFs --- source/mircoders/pdf/PDFGenerator.java | 624 +++++++++++++++++++++++++++++++++ 1 file changed, 624 insertions(+) create mode 100755 source/mircoders/pdf/PDFGenerator.java diff --git a/source/mircoders/pdf/PDFGenerator.java b/source/mircoders/pdf/PDFGenerator.java new file mode 100755 index 00000000..4b2c6958 --- /dev/null +++ b/source/mircoders/pdf/PDFGenerator.java @@ -0,0 +1,624 @@ +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with the com.oreilly.servlet library, any library + * licensed under the Apache Software License, The Sun (tm) Java Advanced + * Imaging library (JAI), The Sun JIMI library (or with modified versions of + * the above that use the same license as the above), and distribute linked + * combinations including the two. You must obey the GNU General Public + * License in all respects for all of the code used other than the above + * mentioned libraries. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If you do + * not wish to do so, delete this exception statement from your version. + */ + +package mircoders.pdf; + +import mir.log.LoggerWrapper; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; + + +import gnu.regexp.RE; +import gnu.regexp.REException; + +import com.lowagie.text.*; +import com.lowagie.text.pdf.*; + +import mir.entity.EntityList; + +import mircoders.entity.EntityContent; +import mircoders.entity.EntityImages; +import mircoders.storage.DatabaseContentToMedia; + +import mir.config.MirPropertiesConfiguration; +import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; + + + +public class PDFGenerator{ + + public Document document; + public PdfWriter writer; + public PdfContentByte cb; + public String localImageDir; + public float currentYPosition; + public int currentPage; + public float pageWidth; + public float pageHeight; + public float verticalMargin; + public float horizontalMargin; + public float topEdge; + public float bottomEdge; + public float rightEdge; + public float leftEdge; + public float footerHeight; + public String footerText; + + protected LoggerWrapper logger; + + + protected MirPropertiesConfiguration configuration; + + + public PDFGenerator(ByteArrayOutputStream out){ + logger = new LoggerWrapper("PDF.PDFGenerator"); + try { + configuration = MirPropertiesConfiguration.instance(); + } + catch (PropertiesConfigExc e) { + throw new RuntimeException("Can't get configuration: " + e.getMessage()); + } + localImageDir=configuration.getString("Producer.Image.Path"); + + // step 1: make a document + + String pageSize = configuration.getString("PDF.Pagesize"); + + if (pageSize.equals("LETTER")){ + document = new Document(PageSize.LETTER); + pageWidth = 612; + pageHeight = 792; + } + else { + document = new Document(PageSize.A4); + pageWidth=595; + pageHeight=842; + } + + try { + + verticalMargin = 20; + horizontalMargin = 20; + + footerHeight = 54; + + topEdge=pageHeight-verticalMargin; + bottomEdge=verticalMargin; + rightEdge=pageWidth-horizontalMargin; + leftEdge=horizontalMargin; + + currentYPosition=topEdge; + currentPage = 1; + + String headerText = configuration.getString("PDF.Title"); + footerText = configuration.getString("PDF.Footer"); + + writer = PdfWriter.getInstance(document, out); + cb = writer.getDirectContent(); + + document.open(); + + + + ColumnText ct = new ColumnText(cb); + //add a basic header + ct.addText(new Phrase(headerText, FontFactory.getFont(FontFactory.COURIER, 24,Font.BOLD))); + + float[] rightCol = {rightEdge,topEdge,rightEdge,topEdge-28}; + float[] leftCol = {leftEdge,topEdge,leftEdge,topEdge-28}; + // int status = ct.go(); + ct.setColumns(leftCol,rightCol); + // int status=ct.go(); + ct.setYLine(topEdge); + ct.setAlignment(Element.ALIGN_CENTER); + ct.go(); + + currentYPosition = currentYPosition - 28; + + } + catch(DocumentException de) { + logger.error(de.getMessage()); + } + } + + public void stop(){ + addFooter(); + document.close(); + } + + public void addIndexItem(EntityContent entityContent){ + try { + float indexLineHeight = 16; + ColumnText ict = new ColumnText(cb); + String theTitle = entityContent.getValue("title"); + String theCreator = entityContent.getValue("creator"); + Phrase titleP=new Phrase(" - " + theTitle,new Font(Font.HELVETICA,12,Font.BOLD)); + Phrase creatorP=new Phrase( " :: " + theCreator,new Font(Font.HELVETICA,12)); + float toYPosition = currentYPosition - indexLineHeight; + float[] leftIndexCols = {leftEdge,currentYPosition,leftEdge,toYPosition}; + float[] rightIndexCols = {rightEdge,currentYPosition,rightEdge,toYPosition}; + ict.addText(titleP); + ict.addText(creatorP); + ict.setColumns(leftIndexCols,rightIndexCols); + ict.setYLine(currentYPosition); + ict.setAlignment(Element.ALIGN_LEFT); + int status=ict.go(); + currentYPosition = toYPosition; + } + catch(DocumentException de) { + logger.error(de.getMessage()); + } + + + + } + + + public void addLine(){ + cb.setLineWidth(1f); + cb.moveTo(rightEdge, currentYPosition-5); + cb.lineTo(leftEdge, currentYPosition-5); + cb.stroke(); + currentYPosition = currentYPosition - 10; + + } + + public void addFooter(){ + try{ + ColumnText fct = new ColumnText(cb); + cb.setLineWidth(1f); + cb.moveTo(rightEdge, bottomEdge+footerHeight-5); + cb.lineTo(leftEdge, bottomEdge+footerHeight-5); + cb.stroke(); + float[] leftFooterCols = {leftEdge,bottomEdge+footerHeight-1,leftEdge,bottomEdge}; + float[] rightFooterCols = {rightEdge,bottomEdge+footerHeight-1,rightEdge,bottomEdge}; + + Paragraph footerP=new Paragraph(footerText,new Font(Font.HELVETICA,12)); + fct.addText(footerP); + + fct.setColumns(leftFooterCols,rightFooterCols); + fct.setYLine(bottomEdge+footerHeight-1); + fct.setAlignment(Element.ALIGN_JUSTIFIED); + int status=fct.go(); + + Paragraph numberP=new Paragraph((new Integer(currentPage)).toString(),new Font(Font.HELVETICA,12,Font.BOLD)); + fct.addText(numberP); + fct.setAlignment(Element.ALIGN_RIGHT); + status=fct.go(); + + } + catch (DocumentException de){ + logger.error(de.getMessage()); + } + + + } + + public void newPage(){ + try{ + //add a footer + addFooter(); + document.newPage(); + currentPage++; + currentYPosition=topEdge; + } + catch(DocumentException de) { + logger.error(de.getMessage()); + } + } + + public boolean enoughY(int heightOfBlockToAdd){ + if ((currentYPosition - heightOfBlockToAdd - footerHeight) < bottomEdge ) + return false; + else + return true; + } + + + public void add(EntityContent entityContent){ + logger.error("adding a content Entity"); + EntityList images=DatabaseContentToMedia.getInstance().getImages(entityContent); + String theTitle = entityContent.getValue("title"); + String theCreator = entityContent.getValue("creator"); + String theDate = entityContent.getValue("webdb_create_formatted"); + String theDescriptionRaw = entityContent.getValue("description"); + String theContentRaw = entityContent.getValue("content_data"); + String theSource = configuration.getString("Producer.ProductionHost") + "/" + configuration.getString("StandardLanguage") + entityContent.getValue("publish_path") + entityContent.getValue("id") + ".shtml"; + + boolean addImageOnLeft = true; + + String theContent = ""; + String theDescription = ""; + + try { + RE re1 = new RE("\r?\n\r?\n"); + String theContent1 = re1.substituteAll(theContentRaw,"BREAKHERE"); + String theDescription1 = re1.substituteAll(theDescriptionRaw,"BREAKHERE"); + + RE re2 = new RE("\r?\n"); + String theContent2 = re2.substituteAll(theContent1," "); + String theDescription2 = re2.substituteAll(theDescription1," "); + + RE re3 = new RE("BREAKHERE"); + theContent = " " + re3.substituteAll(theContent2,"\n "); + theDescription = re3.substituteAll(theDescription2,"\n "); + + } + catch(REException ree){ + logger.error(ree.getMessage()); + } + + + try { + + // make a line (don't worry about the bottomEdge, we should actually write in that area(it's a thin line!) + cb.setLineWidth(1f); + cb.moveTo(rightEdge, currentYPosition-5); + cb.lineTo(leftEdge, currentYPosition-5); + cb.stroke(); + + currentYPosition = currentYPosition - 10; + + + //see if we have room for the author and title + if (! enoughY(36)){ + newPage(); + } + + ColumnText ct = new ColumnText(cb); + + Paragraph titleP=new Paragraph(theTitle+"\n",new Font(Font.HELVETICA,14,Font.BOLD)); + Paragraph whowhenP=new Paragraph(theCreator + " " + theDate ,new Font(Font.HELVETICA,14)); + ct.addText(titleP); + ct.addText(whowhenP); + + ct.setYLine(currentYPosition); + ct.setAlignment(Element.ALIGN_LEFT); + + float toYPosition = currentYPosition - 36; + float[] leftHeadCols = {leftEdge,currentYPosition,leftEdge,toYPosition}; + float[] rightHeadCols = {rightEdge,currentYPosition,rightEdge,toYPosition}; + + ct.setColumns(leftHeadCols,rightHeadCols); + ct.go(); + currentYPosition = toYPosition; + + + // Now add the description, one line at a time, the ct should be empty at this point + + Paragraph descP=new Paragraph(theDescription,new Font(Font.HELVETICA,12,Font.BOLD)); + + ct.addText(descP); + + // every article has a description, so we can assume that: + int status = ColumnText.NO_MORE_COLUMN; + + int descriptionLineHeight=16; + + while ((status & ColumnText.NO_MORE_TEXT) == 0){ + //there is still text left in the description. + logger.error("adding a line to the description"); + + //but is there room on the page? + if (! enoughY(descriptionLineHeight)){ + newPage(); + } + + //now we are set to add a line of descriptive text + toYPosition = currentYPosition - descriptionLineHeight; + float[] leftDescCols = {leftEdge,currentYPosition,leftEdge,toYPosition}; + float[] rightDescCols = {rightEdge,currentYPosition,rightEdge,toYPosition}; + ct.setColumns(leftDescCols,rightDescCols); + ct.setYLine(currentYPosition); + ct.setAlignment(Element.ALIGN_JUSTIFIED); + status=ct.go(); + currentYPosition = toYPosition; + } + + // ok, now on to the meat of the job ahead + + int contentLineHeight=16; + + //let's go ahead and add in all the body text + Paragraph contentP=new Paragraph(theContent,new Font(Font.HELVETICA,10)); + ct.addText(contentP); + //and assume we have at least one line of text in the content + status = ColumnText.NO_MORE_COLUMN; + + int maxImageHeight=250; + int maxImageWidth=250; + + + // let's add a little bit of text, like a couple of lines + int x = 0; + while (((status & ColumnText.NO_MORE_TEXT) == 0) && x<3){ + //in case we have some text left + + logger.error("adding a line to the content"); + + //but is there room on the page? + if (! enoughY(contentLineHeight)){ + newPage(); + } + + //now we are set to add a line of content text + toYPosition = currentYPosition - contentLineHeight; + float[] leftContentCols = {leftEdge,currentYPosition,leftEdge,toYPosition}; + float[] rightContentCols = {rightEdge,currentYPosition,rightEdge,toYPosition}; + ct.setColumns(leftContentCols,rightContentCols); + ct.setYLine(currentYPosition); + ct.setAlignment(Element.ALIGN_JUSTIFIED); + status=ct.go(); + currentYPosition = toYPosition; + x++; + } + + + + while (images.hasNext()){ + + EntityImages currentImage=(EntityImages) images.next(); + float img_width=(new Float(currentImage.getValue("img_width"))).floatValue(); + float img_height=(new Float(currentImage.getValue("img_height"))).floatValue(); + if (img_height>maxImageHeight){ + img_width=(new Float((new Float(img_width*(maxImageHeight/img_height))).intValue())).floatValue(); + img_height=maxImageHeight; + } + if (img_width>maxImageWidth){ + img_height=(new Float((new Float(img_height*(maxImageWidth/img_width))).intValue())).floatValue(); + img_width=maxImageWidth; + } + + String img_title=currentImage.getValue("title"); + String img_path=currentImage.getValue("publish_path"); + + + + + if ((status & ColumnText.NO_MORE_TEXT) == 0){ + // there is still text, so add an image which will have text wrapped around it, then add the text which + // will be on the left or the right of the image + + float templateMinimumHeight = img_height+20; + float templateWidth = img_width+10; + + float templateHeight = templateMinimumHeight+contentLineHeight-(templateMinimumHeight % contentLineHeight); + + + PdfTemplate template = cb.createTemplate(templateWidth,templateHeight); + + + //here we need a page check + if (! enoughY((new Float(templateHeight)).intValue())){ + //ok, well just fill text to the bottom then + toYPosition = bottomEdge+footerHeight; + float[] leftBottomCols = {leftEdge,currentYPosition,leftEdge,toYPosition}; + float[] rightBottomCols = {rightEdge,currentYPosition,rightEdge,toYPosition}; + ct.setColumns(leftBottomCols,rightBottomCols); + ct.setYLine(currentYPosition); + ct.setAlignment(Element.ALIGN_JUSTIFIED); + status=ct.go(); + newPage(); + } + + toYPosition=currentYPosition - templateHeight; + + Image theImage = Image.getInstance(localImageDir+img_path); + theImage.scaleAbsolute(img_width,img_height); + theImage.setAbsolutePosition(5,13); + template.addImage(theImage); + template.beginText(); + BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); + template.setFontAndSize(bf, 8); + template.setTextMatrix(5, 3); + template.showText(img_title); + template.endText(); + + + float leftImageTextEdge=leftEdge; + float rightImageTextEdge=rightEdge; + + + if (addImageOnLeft){ + cb.addTemplate(template,leftEdge,toYPosition); + leftImageTextEdge=leftEdge+templateWidth+5; + addImageOnLeft = false; + } + else { + cb.addTemplate(template,rightEdge-templateWidth,toYPosition); + rightImageTextEdge = rightEdge-templateWidth-5; + addImageOnLeft = true; + } + + logger.error("adding template at " + leftEdge + "," + toYPosition); + + //and fill some text while we are at it + + float[] leftBottomCols = {leftImageTextEdge,currentYPosition,leftImageTextEdge,toYPosition}; + float[] rightBottomCols = {rightImageTextEdge,currentYPosition,rightImageTextEdge,toYPosition}; + ct.setColumns(leftBottomCols,rightBottomCols); + ct.setYLine(currentYPosition); + ct.setAlignment(Element.ALIGN_JUSTIFIED); + status=ct.go(); + + currentYPosition=toYPosition; + + + } + else { + //add an image on the left with a big caption to the right + currentYPosition = currentYPosition - 10; + float templateMinimumHeight = img_height; + float templateWidth = img_width; + float templateHeight = templateMinimumHeight+contentLineHeight-(templateMinimumHeight % contentLineHeight); + PdfTemplate template = cb.createTemplate(templateWidth,templateHeight); + if (! enoughY((new Float(templateHeight)).intValue())){ + newPage(); + } + toYPosition=currentYPosition - templateHeight; + Image theImage = Image.getInstance(localImageDir+img_path); + theImage.setAbsolutePosition(0,13); + theImage.scaleAbsolute(img_width,img_height); + template.addImage(theImage); + + cb.addTemplate(template,leftEdge,toYPosition); + + // add a big caption + ColumnText cct = new ColumnText(cb); + float[] leftCaptionCols = {leftEdge+templateWidth+5,currentYPosition-5,leftEdge+templateWidth+5,toYPosition}; + float[] rightCaptionCols = {rightEdge,currentYPosition-5,rightEdge,toYPosition}; + + Paragraph captionP=new Paragraph(img_title,new Font(Font.HELVETICA,16,Font.BOLD)); + cct.addText(captionP); + cct.setColumns(leftCaptionCols,rightCaptionCols); + cct.setYLine(currentYPosition-5); + cct.setAlignment(Element.ALIGN_LEFT); + cct.go(); + + + + currentYPosition=toYPosition; + + + } + + } + + + while ((status & ColumnText.NO_MORE_TEXT) == 0){ + //in case we have some text left + + logger.error("adding a line to the content"); + + //but is there room on the page? + if (! enoughY(contentLineHeight)){ + newPage(); + } + + //now we are set to add a line of content text + toYPosition = currentYPosition - contentLineHeight; + float[] leftContentCols = {leftEdge,currentYPosition,leftEdge,toYPosition}; + float[] rightContentCols = {rightEdge,currentYPosition,rightEdge,toYPosition}; + ct.setColumns(leftContentCols,rightContentCols); + ct.setYLine(currentYPosition); + ct.setAlignment(Element.ALIGN_JUSTIFIED); + status=ct.go(); + currentYPosition = toYPosition; + + } + + // and add the source link + + toYPosition = currentYPosition - contentLineHeight; + float[] leftSourceCols = {leftEdge,currentYPosition,leftEdge,toYPosition}; + float[] rightSourceCols = {rightEdge,currentYPosition,rightEdge,toYPosition}; + ct.setColumns(leftSourceCols,rightSourceCols); + Paragraph sourceP = new Paragraph(theSource,new Font(Font.COURIER,12,Font.BOLD)); + ct.addText(sourceP); + ct.setYLine(currentYPosition); + ct.setAlignment(Element.ALIGN_RIGHT); + status=ct.go(); + currentYPosition = toYPosition; + + + + + + } + catch(DocumentException de) { + logger.error(de.getMessage()); + } + catch(MalformedURLException de) { + logger.error(de.getMessage()); + } + catch(IOException de) { + logger.error(de.getMessage()); + } + /* while(images.hasNext()){ + + EntityImages currentImage=(EntityImages) images.next(); + float img_width=(new Float(currentImage.getValue("img_width"))).floatValue(); + float img_height=(new Float(currentImage.getValue("img_height"))).floatValue(); + if (img_width>250){ + img_height=(new Float((new Float(img_height*(250.0F/img_width))).intValue())).floatValue(); + img_width=250.0F; + } + String img_title=currentImage.getValue("title"); + String img_path=currentImage.getValue("publish_path"); + + PdfTemplate template = cb.createTemplate(img_width+10, img_height+20); + try{ + Image theImage = Image.getInstance(localImageDir+img_path); + theImage.setAbsolutePosition(5,13); + template.addImage(theImage); + template.beginText(); + BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); + template.setFontAndSize(bf, 8); + template.setTextMatrix(5, 3); + template.showText(img_title); + template.endText(); + ImgTemplate it = new ImgTemplate(template); + it.setAlignment(Image.RIGHT | Image.TEXTWRAP); + document.add(it); + + document.add(new Paragraph("this is a test of adding some text to see if we bump down a line when there is some text")); + + } + catch(DocumentException de) { + System.err.println(de.getMessage()); + } + catch(IOException ioe) { + System.err.println(ioe.getMessage()); + } + } */ + + /* + try { + + + Paragraph p=new Paragraph(theContent,new Font(Font.HELVETICA,11)); + p.setAlignment(Paragraph.ALIGN_JUSTIFIED); + + document.add(p); + } + catch(DocumentException de) { + System.err.println(de.getMessage()); + } + + */ + + } + +} + + -- 2.11.0