1 /* 2 * $Id$ 3 * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer 4 * 5 * Permission is hereby granted, free of charge, to any person 6 * obtaining a copy of this software and associated documentation 7 * files (the "Software"), to deal in the Software without 8 * restriction, including without limitation the rights to use, 9 * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following 12 * conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 /* 28 * This class was originally published under the MPL by Bruno Lowagie 29 * and Carsten Hammer. 30 * It was a part of iText, a Java-PDF library. You can now use it under 31 * the MIT License; for backward compatibility you can also use it under 32 * the MPL version 1.1: http://www.mozilla.org/MPL/ 33 * A copy of the MPL license is bundled with the source code FYI. 34 */ 35 36 package com.lowagie.toolbox.plugins; 37 38 import java.io.File; 39 import java.io.FileOutputStream; 40 41 import javax.swing.JInternalFrame; 42 import javax.swing.JOptionPane; 43 44 import com.lowagie.text.Document; 45 import com.lowagie.text.PageSize; 46 import com.lowagie.text.Rectangle; 47 import com.lowagie.text.pdf.PdfContentByte; 48 import com.lowagie.text.pdf.PdfImportedPage; 49 import com.lowagie.text.pdf.PdfReader; 50 import com.lowagie.text.pdf.PdfWriter; 51 import com.lowagie.toolbox.AbstractTool; 52 import com.lowagie.toolbox.arguments.AbstractArgument; 53 import com.lowagie.toolbox.arguments.FileArgument; 54 import com.lowagie.toolbox.arguments.OptionArgument; 55 import com.lowagie.toolbox.arguments.filters.PdfFilter; 56 57 /** 58 * Generates a PDF file that is usable as Handout. 59 * @since 2.1.1 (imported from itexttoolbox project) 60 */ 61 public class Handouts extends AbstractTool { 62 63 static { 64 addVersion("$Id$"); 65 } 66 67 /** 68 * Constructs a Handouts object. 69 */ Handouts()70 public Handouts() { 71 arguments.add(new FileArgument(this, "srcfile", "The file you want to convert", false, new PdfFilter())); 72 arguments.add(new FileArgument(this, "destfile", "The file to which the Handout has to be written", true, new PdfFilter())); 73 OptionArgument oa = new OptionArgument(this, "pages", "The number of pages you want on one handout page"); 74 oa.addOption("2 pages on 1", "2"); 75 oa.addOption("3 pages on 1", "3"); 76 oa.addOption("4 pages on 1", "4"); 77 oa.addOption("5 pages on 1", "5"); 78 oa.addOption("6 pages on 1", "6"); 79 oa.addOption("7 pages on 1", "7"); 80 oa.addOption("8 pages on 1", "8"); 81 arguments.add(oa); 82 } 83 84 /** 85 * @see com.lowagie.toolbox.AbstractTool#createFrame() 86 */ createFrame()87 protected void createFrame() { 88 internalFrame = new JInternalFrame("Handouts", true, false, true); 89 internalFrame.setSize(300, 80); 90 internalFrame.setJMenuBar(getMenubar()); 91 System.out.println("=== Handouts OPENED ==="); 92 } 93 94 /** 95 * @see com.lowagie.toolbox.AbstractTool#execute() 96 */ execute()97 public void execute() { 98 try { 99 if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); 100 File src = (File)getValue("srcfile"); 101 if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); 102 File dest = (File)getValue("destfile"); 103 int pages; 104 try { 105 pages = Integer.parseInt((String) getValue("pages")); 106 } 107 catch(Exception e) { 108 pages = 4; 109 } 110 111 float x1 = 30f; 112 float x2 = 280f; 113 float x3 = 320f; 114 float x4 = 565f; 115 116 float[] y1 = new float[pages]; 117 float[] y2 = new float[pages]; 118 119 float height = (778f - (20f * (pages - 1))) / pages; 120 y1[0] = 812f; 121 y2[0] = 812f - height; 122 123 for (int i = 1; i < pages; i++) { 124 y1[i] = y2[i - 1] - 20f; 125 y2[i] = y1[i] - height; 126 } 127 128 // we create a reader for a certain document 129 PdfReader reader = new PdfReader(src.getAbsolutePath()); 130 // we retrieve the total number of pages 131 int n = reader.getNumberOfPages(); 132 System.out.println("There are " + n + " pages in the original file."); 133 134 // step 1: creation of a document-object 135 Document document = new Document(PageSize.A4); 136 // step 2: we create a writer that listens to the document 137 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest)); 138 // step 3: we open the document 139 document.open(); 140 PdfContentByte cb = writer.getDirectContent(); 141 PdfImportedPage page; 142 int rotation; 143 int i = 0; 144 int p = 0; 145 // step 4: we add content 146 while (i < n) { 147 i++; 148 Rectangle rect = reader.getPageSizeWithRotation(i); 149 float factorx = (x2 - x1) / rect.getWidth(); 150 float factory = (y1[p] - y2[p]) / rect.getHeight(); 151 float factor = (factorx < factory ? factorx : factory); 152 float dx = (factorx == factor ? 0f : ((x2 - x1) - rect.getWidth() * factor) / 2f); 153 float dy = (factory == factor ? 0f : ((y1[p] - y2[p]) - rect.getHeight() * factor) / 2f); 154 page = writer.getImportedPage(reader, i); 155 rotation = reader.getPageRotation(i); 156 if (rotation == 90 || rotation == 270) { 157 cb.addTemplate(page, 0, -factor, factor, 0, x1 + dx, y2[p] + dy + rect.getHeight() * factor); 158 } 159 else { 160 cb.addTemplate(page, factor, 0, 0, factor, x1 + dx, y2[p] + dy); 161 } 162 cb.setRGBColorStroke(0xC0, 0xC0, 0xC0); 163 cb.rectangle(x3 - 5f, y2[p] - 5f, x4 - x3 + 10f, y1[p] - y2[p] + 10f); 164 for (float l = y1[p] - 19; l > y2[p]; l -= 16) { 165 cb.moveTo(x3, l); 166 cb.lineTo(x4, l); 167 } 168 cb.rectangle(x1 + dx, y2[p] + dy, rect.getWidth() * factor, rect.getHeight() * factor); 169 cb.stroke(); 170 System.out.println("Processed page " + i); 171 p++; 172 if (p == pages) { 173 p = 0; 174 document.newPage(); 175 } 176 } 177 // step 5: we close the document 178 document.close(); 179 } 180 catch(Exception e) { 181 JOptionPane.showMessageDialog(internalFrame, 182 e.getMessage(), 183 e.getClass().getName(), 184 JOptionPane.ERROR_MESSAGE); 185 System.err.println(e.getMessage()); 186 } 187 } 188 189 /** 190 * 191 * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) 192 * @param arg StringArgument 193 */ valueHasChanged(AbstractArgument arg)194 public void valueHasChanged(AbstractArgument arg) { 195 if (internalFrame == null) { 196 // if the internal frame is null, the tool was called from the command line 197 return; 198 } 199 // represent the changes of the argument in the internal frame 200 } 201 202 203 /** 204 * Converts a PDF file to a PDF file usable as Handout. 205 * 206 * @param args String[] 207 */ main(String[] args)208 public static void main(String[] args) { 209 Handouts tool = new Handouts(); 210 if (args.length < 2) { 211 System.err.println(tool.getUsage()); 212 } 213 tool.setMainArguments(args); 214 tool.execute(); 215 } 216 217 /** 218 * 219 * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() 220 * @throws InstantiationException 221 * @return File 222 */ getDestPathPDF()223 protected File getDestPathPDF() throws InstantiationException { 224 return (File)getValue("destfile"); 225 } 226 } 227