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