001/*
002 *  InterMergePDF
003 *
004 *  $URL: svn://svn.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/tools/pdf/InterMergePDF.java $
005 *  $REVISION: $
006 *  Copyright (C) 2003 Tom Gutwin
007 *  tgutwin@webarts.bc.ca
008 *
009 *
010 *  This program is free software; you can redistribute it and/or
011 *  modify it under the terms of the GNU General Public License
012 *  as published by the Free Software Foundation; either version 2
013 *  of the License, or any later version.
014 *
015 *  This program is distributed in the hope that it will be useful,
016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
018 *  GNU General Public License for more details.
019 *
020 *  You should have received a copy of the GNU General Public License
021 *  along with the jEdit program; if not, write to the Free Software
022 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
023 */
024
025package ca.bc.webarts.tools.pdf;
026
027import java.io.File;
028import java.io.FileNotFoundException;
029import java.io.FileOutputStream;
030
031import com.itextpdf.text.Document;
032import com.itextpdf.text.PageSize;
033import com.itextpdf.text.pdf.PdfContentByte;
034import com.itextpdf.text.pdf.PdfImportedPage;
035import com.itextpdf.text.pdf.PdfReader;
036import com.itextpdf.text.pdf.PdfWriter;
037import com.itextpdf.text.Rectangle;
038
039
040/**
041 *  A tool to manipulate combine 2 PDF docs Page by page. One page from the
042 * first doc then one page from the second doc.
043 *  <br>
044 *  This class can be called from the commandline or instantiated and used from
045 *  other Java Objects.<br><br>
046 *  <b><u>Commandline Syntax:</u></b><br>
047 *  java InterMergePDF OddPagesPDFFilename EvenPagesPDFFilename MergedPDFFilename <br />
048 *
049 * @author    tgutwin
050 */
051public class InterMergePDF
052{
053  /** the filename for the resultant merged PDF. **/
054  private String mergedPDFName_ = null;
055
056  /** the filename to use for the ODD pages. **/
057  private String oddPagePDFName_ = null;
058
059  /** the filename to use for the EVEN pages. **/
060  private String evenPagePDFName_ = null;
061
062
063  /**
064   * Constructor that takes the 3 required filename.
065   **/
066   public InterMergePDF(String oddPagePDFName,
067                        String evenPagePDFName,
068                        String mergedPDFName) throws FileNotFoundException
069   {
070     setMergedPDFName(mergedPDFName);
071     setOddPagePDFName(oddPagePDFName);
072     setEvenPagePDFName(evenPagePDFName);
073   }
074
075
076  /**
077   *  The main program for the InterMergePDF class
078   *
079   * @param  args  The command line arguments (file names)
080   */
081  public static void main(String[] args)
082  {
083    if (args!=null && args.length == 3)
084    {
085      //System.out.println("Merging "+args[0] + ", "+ args[1] + " and "+ args[2]);
086      try
087      {
088        InterMergePDF instance = new InterMergePDF(args[0], args[1], args[2]);
089        instance.doMerge();
090      }
091      catch (FileNotFoundException FNFEx)
092      {
093        System.out.println("You provided crappy commandline arguments.");
094        System.out.println("SYNTAX: java InterMergePDF OddPagesPDFFilename EvenPagesPDFFilename MergedPDFFilename");
095      }
096      catch (Exception ex)
097      {
098        System.out.println("You provided crappy commandline arguments.");
099        ex.printStackTrace();
100        System.out.println("SYNTAX: java InterMergePDF OddPagesPDFFilename EvenPagesPDFFilename MergedPDFFilename");
101      }
102    }
103    else
104    {
105      System.out.println("You provided the wrong number of crappy commandline arguments.");
106      System.out.println("SYNTAX: java InterMergePDF OddPagesPDFFilename EvenPagesPDFFilename MergedPDFFilename");
107    }
108  }
109
110
111  /**
112   * Executes the reading of a PDF file into a Document Object.
113   *
114   * @return success or failure
115   **/
116  private Document parsePDFFile(String inFileName)
117  {
118    Document retVal = null;
119    String outFileName =
120        inFileName.substring(0, inFileName.length()-4)+".tmp.pdf";
121    try
122    {
123      // we create a reader for a certain document
124      System.out.println("Reading: " + inFileName);
125      PdfReader reader = new PdfReader(inFileName);
126      float width_DPI = reader.getPageSize(1).getWidth();
127      float height_DPI = reader.getPageSize(1).getHeight();
128      float width = width_DPI / 72.0f;
129      float height = height_DPI / 72.0f;
130
131      // step 1: creation of a document-object
132      Rectangle newPageSize = null;
133      newPageSize = reader.getPageSize(1);
134
135      // we retrieve the total number of pages
136      int numPages = reader.getNumberOfPages();
137
138      Document document =
139          new Document(newPageSize, 0, 0, 0, 0);// Margins: left, right,top, bottom
140
141      // step 2: we create a writer that listens to the document
142      System.out.println("Writing: " + outFileName);
143      FileOutputStream outFileStream = new FileOutputStream(outFileName);
144      PdfWriter writer = PdfWriter.getInstance(document, outFileStream);
145
146      // step 3: we open the document
147      document.open();
148
149      // step 4: calculate the new scaling / layout postion
150      PdfContentByte cb = writer.getDirectContent();
151      System.out.println("There are " + numPages +
152          " pages in the document.");
153      PdfImportedPage currentPDFPage;
154      int currentPageNum = 0;
155
156      /*
157       *  step 5: Start Copying the pages to the new Doc
158       *  ******* ***************************************
159       */
160      while (currentPageNum < numPages)
161      {
162        document.newPage();
163        currentPDFPage = writer.getImportedPage(reader, ++currentPageNum);
164        cb.addTemplate(currentPDFPage, 0.0f, 0.0f);
165      }
166
167      // step 6: we close the document
168      document.close();
169      retVal = document;
170    }
171    catch (Exception de)
172    {
173      de.printStackTrace();
174      retVal = null;
175    }
176
177    return retVal;
178  }
179
180
181  /**
182   * Executes the merge as specified by the class parms.
183   *
184   * @return success or failure
185   **/
186  public boolean doMerge()
187  {
188    boolean retVal = true;
189    //System.out.println("Merging "+oddPagePDFName_ + " and "+ evenPagePDFName_);
190    try
191    {
192      // we create a reader for a certain document
193      PdfReader oddReader = new PdfReader(oddPagePDFName_);
194      PdfReader evenReader = new PdfReader(evenPagePDFName_);
195
196
197      float oddWidth_DPI = oddReader.getPageSize(1).getWidth();
198      float oddHeight_DPI = oddReader.getPageSize(1).getHeight();
199      float oddWidth = oddWidth_DPI / 72.0f;
200      float oddHeight = oddHeight_DPI / 72.0f;
201      float evenWidth_DPI = evenReader.getPageSize(1).getWidth();
202      float evenHeight_DPI = evenReader.getPageSize(1).getHeight();
203      float evenWidth = evenWidth_DPI / 72.0f;
204      float evenHeight = evenHeight_DPI / 72.0f;
205
206      // step 1: creation of a document-object
207      Rectangle newPageSize = oddReader.getPageSize(1);
208      Document document =
209          new Document(newPageSize, 0, 0, 0, 0);// Margins: left, right,top, bottom
210
211      // we retrieve the total number of pages
212      int numPages = oddReader.getNumberOfPages() + evenReader.getNumberOfPages();
213      /*System.out.println("Cropping " + numPages + " - " + width + "x" + height +
214          " pages by (left=" + leftCropBorder_ + " right=" + rightCropBorder_ +
215          " Top=" + topCropBorder_ + " bottom=" + bottomCropBorder_ +
216          " scale=" + scale_ + ")");
217      System.out.println("New Page Size: " +  newPageSize.getWidth()/ 72.0f + "x" +
218                          newPageSize.getHeight()/ 72.0f);*/
219
220      // step 2: we create a writer that listens to the document
221      System.out.println("Writing: " + mergedPDFName_);
222      FileOutputStream outFileStream = new FileOutputStream(mergedPDFName_);
223      PdfWriter writer = PdfWriter.getInstance(document, outFileStream);
224
225      // step 3: we open the document
226      document.open();
227
228      // step 4: calculate the new scaling / layout postion
229      PdfContentByte cb = writer.getDirectContent();
230      System.out.println("There are " + numPages +
231          " pages in the document.");
232      PdfImportedPage leftPage;
233      PdfImportedPage rightPage;
234      int currentLeftPage = 1;
235      int currentRightPage = 1;
236      int numPagesTransfered = 0;
237
238      /*
239       *  step 5: Start Copying the pages to the new Doc (in 2Up format)
240       *  ******* ******************************************************
241       */
242      while (numPagesTransfered < numPages)
243      {
244        //System.out.println(currentLeftPage+" "+currentRightPage);
245        if ((currentLeftPage+currentRightPage) % 2 !=0)
246        {
247          // Even Page
248          document.newPage();
249          leftPage = writer.getImportedPage(evenReader, currentLeftPage);
250          // Check if there are still pages left to merge in
251          if ( leftPage != null )
252          {
253            cb.addTemplate(leftPage, 0,0);
254            currentLeftPage++;
255            numPagesTransfered++;
256          }
257          else
258          {
259            // put a oddPage in instead
260            leftPage = writer.getImportedPage(oddReader, currentRightPage);
261            if ( leftPage != null )
262            {
263              cb.addTemplate(leftPage, 0,0);
264              currentRightPage++;
265              numPagesTransfered++;
266            }
267            else
268            {
269              System.out.println("Page numeber error");
270              break;
271            }
272          }
273        }
274        else
275        {
276          //ODD Page
277          document.newPage();
278          rightPage = writer.getImportedPage(oddReader, currentRightPage);
279          // Check if there are still pages left to merge in
280          if ( rightPage != null )
281          {
282            cb.addTemplate(rightPage, 0,0);
283            currentRightPage++;
284            numPagesTransfered++;
285          }
286          else
287          {
288            // put a leftPage in
289            rightPage = writer.getImportedPage(evenReader, currentLeftPage);
290            if ( rightPage != null )
291            {
292              cb.addTemplate(rightPage, 0,0);
293              currentLeftPage++;
294              numPagesTransfered++;
295            }
296            else
297            {
298              System.out.println("Page numeber error");
299              break;
300            }
301          }
302        }
303      }
304
305      // step 6: we close the document
306      document.close();
307    }
308    catch (Exception de)
309    {
310      de.printStackTrace();
311      retVal = false;
312    }
313
314    return retVal;
315  }
316
317
318  /**
319   * Setter for the mergedPDFName_ field.
320   **/
321  public void setMergedPDFName(String mergedPDFName)
322  {
323    this.mergedPDFName_ = mergedPDFName;
324  }
325
326
327  /**
328   * Getter for the mergedPDFName_ field.
329   **/
330  public String getMergedPDFName()
331  {
332    return mergedPDFName_;
333  }
334
335
336  /**
337   * Setter for the oddPagePDFName_ field.
338   **/
339  public void setOddPagePDFName(String oddPagePDFName)
340  {
341    this.oddPagePDFName_ = oddPagePDFName;
342  }
343
344
345  /**
346   * Getter for the oddPagePDFName_ field.
347   **/
348  public String getOddPagePDFName_()
349  {
350    return oddPagePDFName_;
351  }
352
353
354  /**
355   * Setter for the evenPagePDFName_ field.
356   **/
357  public void setEvenPagePDFName(String evenPagePDFName)
358  {
359    this.evenPagePDFName_ = evenPagePDFName;
360  }
361
362
363  /**
364   * Getter for the evenPagePDFName_ field.
365   **/
366  public String getEvenPagePDFName_()
367  {
368    return evenPagePDFName_;
369  }
370
371
372
373}