/* * $Id: PDFDocument.java,v 1.4 2007/09/22 12:58:40 gil1 Exp $ * * $Date: 2007/09/22 12:58:40 $ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package gnu.jpdf; import java.awt.FontFormatException; import java.awt.Image; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.Vector; import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; /** *
* This class is the base of the PDF generator. A PDFDocument class is created * for a document, and each page, object, annotation, etc is added to the * document. Once complete, the document can be written to an OutputStream, and * the PDF document's internal structures are kept in sync.
* *
* Note that most programmers using this package will NEVER access one of these
* objects directly. Most everything can be done using PDFJob and
* PDFGraphics, so you don't need to directly instantiate a
* PDFDocument
* ezb - 20011115 - Wondering if the constructors should even be public. When * would someone want to make one of these and manipulate it outside the context * of a job and graphics object?
* * @author Peter T Mount, http://www.retep.org.uk/pdf/ * @author Eric Z. Beard, ericzbeard@hotmail.com * @author Gilbert DeLeeuw, gil1@users.sourceforge.net * @version $Revision: 1.4 $, $Date: 2007/09/22 12:58:40 $ */ public class PDFDocument implements Serializable { /* * NOTE: This class originated in uk.org.retep.pdf, by Peter T. Mount, and it * has been modified by Eric Z. Beard, ericzbeard@hotmail.com. The * package name was changed to gnu.jpdf and several inner classes were * moved out into their own files. */ /** * This is used to allocate objects a unique serial number in the document. */ protected int objser; /** * This vector contains each indirect object within the document. */ protected Vector* This page mode indicates that the document should be opened just with the * page visible. This is the default
*/ public static final int USENONE = 0; /** ** This page mode indicates that the Outlines should also be displayed when * the document is opened.
*/ public static final int USEOUTLINES = 1; /** ** This page mode indicates that the Thumbnails should be visible when the * document first opens.
*/ public static final int USETHUMBS = 2; /** ** This page mode indicates that when the document is opened, it is * displayed in full-screen-mode. There is no menu bar, window controls nor * any other window present.
*/ public static final int FULLSCREEN = 3; /** ** These map the page modes just defined to the pagemodes setting of PDF. *
*/ public static final String PDF_PAGE_MODES[] = { "/UseNone", "/UseOutlines", "/UseThumbs", "/FullScreen" }; /** * This is used to provide a unique name for a font */ private int fontid = 0; /** ** This is used to provide a unique name for an image
*/ private int imageid = 0; /** * This holds the current fonts */ private Vector* This creates a PDF document with the default pagemode
*/ public PDFDocument() { this(USENONE); } /** ** This creates a PDF document
* * @param pagemode an int, determines how the document will present itself * to the viewer when it first opens. */ public PDFDocument(int pagemode) { objser = 1; objects = new Vector* Once added, it is allocated a unique serial number. * *
* Note: Not all object are added directly using this method. Some * objects which have Kids (in PDF sub-objects or children are called Kids) * will have their own add() method, which will call this one internally. * * @param obj The PDFObject to add to the document * @return the unique serial number for this object. */ public synchronized int add(PDFObject obj) { objects.addElement(obj); obj.objser = objser++; // create a new serial number obj.pdfDocument = this; // so they can find the document they belong to // If its a page, then add it to the pages collection if (obj instanceof PDFPage) { pdfPageList.add((PDFPage) obj); } return obj.objser; } /** *
* This returns a specific page. It's used mainly when using a Serialized * template file.
* * ?? How does a serialized template file work ??? * * @param page page number to return * @return PDFPage at that position */ public PDFPage getPage(int page) { return pdfPageList.getPage(page); } /** * @return the root outline */ public PDFOutline getOutline() { if (outline == null) { outline = new PDFOutline(); catalog.setOutline(outline); } return outline; } /** * This returns a font of the specified type and font. If the font has not * been defined, it creates a new font in the PDF document, and returns it. * * @param type PDF Font Type - usually "/Type1" * @param font Java font name * @param style java.awt.Font style (NORMAL, BOLD etc) * @return PDFFont defining this font */ public PDFFont getFont(String type, String font, int style) { for (PDFFont ft : fonts) { if (ft.equals(type, font, style)) { return ft; } } // the font wasn't found, so create it fontid++; PDFFont ft = new PDFFont("/F" + fontid, type, font, style); add(ft); fonts.addElement(ft); return ft; } public PDFFont getEmbeddedFont(String font, int style, File file) throws FileNotFoundException, IOException { for (PDFFont ft : fonts) { if (ft.equals("/TrueType", font, style)) { return ft; } } PDFStream fontFile2 = new PDFStream() { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/Length1 ".getBytes("UTF-8")); os.write(Integer.toString(buf.size()).getBytes("UTF-8")); os.write("\n".getBytes("UTF-8")); writeStream(os); } }; fontFile2.setDeflate(true); OutputStream ff2Os = fontFile2.getOutputStream(); InputStream is = new FileInputStream(file); byte buf[] = new byte[1024]; int cnt = 0; while ((cnt = is.read(buf)) > 0) { ff2Os.write(buf, 0, cnt); } is.close(); //ff2Os.write("AHOJ".getBytes("UTF-8")); add(fontFile2); // the font wasn't found, so create it fontid++; final TtfParser par = new TtfParser(); try { par.loadFromTTF(file); } catch (FontFormatException ex) { Logger.getLogger(PDFDocument.class.getName()).log(Level.SEVERE, null, ex); } PDFStream cidToGidMap = new PDFStream(); cidToGidMap.getOutputStream().write(par.getCidtogidmap()); cidToGidMap.setDeflate(true); add(cidToGidMap); //ToUnicode map for Identity-H stream String uniIdentityH = "/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n/WMode 0 def\n1 begincodespacerange\n<0000>